java qq 密码加密_java-QQ加密算法 | 学步园

public QQDataTransformer(String key) {

this(key, "qq");

}

public QQDataTransformer(String key, String name) {

super(key, name);

// TODO Auto-generated constructor stub

}

@Override

public byte[] encode(byte[] data) throws TransformerException {

MessageDigest md5;

try {

md5 = MessageDigest.getInstance("MD5");

byte[] keyBytes = md5.digest(StringTools.getUTF8Bytes(this.key));

swapBytes(keyBytes);

reverseBits(keyBytes);

byte[] enc = new QQCrypter().encrypt(data, keyBytes);

enc = Base64.encode(enc);

return enc;

} catch (NoSuchAlgorithmException e) {

throw new TransformerException(e);

} catch (CodecException e) {

throw new TransformerException(e);

}

}

@Override

public String encode(String data) throws TransformerException {

return StringTools.getUTF8String(encode(StringTools.getUTF8Bytes(data)));

}

@Override

public byte[] decode(byte[] data) throws TransformerException {

MessageDigest md5;

try {

md5 = MessageDigest.getInstance("MD5");

byte[] keyBytes = md5.digest(StringTools.getUTF8Bytes(key));

swapBytes(keyBytes);

reverseBits(keyBytes);

byte[] dec = Base64.decode(data);

byte[] rtn = new QQCrypter().decrypt(dec, keyBytes);

return rtn;

} catch (NoSuchAlgorithmException e) {

throw new TransformerException(e);

} catch (CodecException e) {

throw new TransformerException(e);

}

}

@Override

public String decode(String data) throws TransformerException {

return StringTools.getUTF8String(decode(StringTools.getUTF8Bytes(data)));

}

private static void swapBytes(byte[] b) {

for (int i = 0; i < b.length; i += 2) {

byte tmp = b[i];

b[i] = b[i + 1];

b[i + 1] = tmp;

}

}

private static void reverseBits(byte[] b) {

for (int i = 0; i < b.length; i++)

b[i] ^= 0xFF;

}

static class QQCrypter {

private byte[] plain;

private byte[] prePlain;

private byte[] out;

private int crypt, preCrypt;

private int pos;

private int padding;

private byte[] key;

private boolean header = true;

private int contextStart;

private static Random random = new Random();

private ByteArrayOutputStream baos;

public QQCrypter() {

baos = new ByteArrayOutputStream(8);

}

private static long getUnsignedInt(byte[] in, int offset, int len) {

long ret = 0;

int end = 0;

if (len > 8)

end = offset + 8;

else

end = offset + len;

for (int i = offset; i < end; i++) {

ret <<= 8;

ret |= in[i] & 0xff;

}

return (ret & 0xffffffffl) | (ret >>> 32);

}

public byte[] decrypt(byte[] in, int offset, int len, byte[] k) {

if(k == null)

return null;

crypt = preCrypt = 0;

this.key = k;

byte[] m = new byte[offset + 8];

if((len % 8 != 0) || (len < 16)) return null;

prePlain = decipher(in, offset);

pos = prePlain[0] & 0x7;

int count = len - pos - 10;

if(count < 0) return null;

for(int i = offset; i < m.length; i++)

m[i] = 0;

out = new byte[count];

preCrypt = 0;

crypt = 8;

contextStart = 8;

pos++;

padding = 1;

while(padding <= 2) {

if(pos < 8) {

pos++;

padding++;

}

if(pos == 8) {

m = in;

if(!decrypt8Bytes(in, offset, len)) return null;

}

}

int i = 0;

while(count != 0) {

if(pos < 8) {

out[i] = (byte)(m[offset + preCrypt + pos] ^ prePlain[pos]);

i++;

count--;

pos++;

}

if(pos == 8) {

m = in;

preCrypt = crypt - 8;

if(!decrypt8Bytes(in, offset, len))

return null;

}

}

for(padding = 1; padding < 8; padding++) {

if(pos < 8) {

if((m[offset + preCrypt + pos] ^ prePlain[pos]) != 0)

return null;

pos++;

}

if(pos == 8) {

m = in;

preCrypt = crypt;

if(!decrypt8Bytes(in, offset, len))

return null;

}

}

return out;

}

public byte[] decrypt(byte[] in, byte[] k) {

return decrypt(in, 0, in.length, k);

}

public byte[] encrypt(byte[] in, int offset, int len, byte[] k) {

if(k == null)

return in;

plain = new byte[8];

prePlain = new byte[8];

pos = 1;

padding = 0;

crypt = preCrypt = 0;

this.key = k;

header = true;

pos = (len + 0x0A) % 8;

if(pos != 0)

pos = 8 - pos;

out = new byte[len + pos + 10];

plain[0] = (byte)((rand() & 0xF8) | pos);

for(int i = 1; i <= pos; i++)

plain[i] = (byte)(rand() & 0xFF);

pos++;

for(int i = 0; i < 8; i++)

prePlain[i] = 0x0;

padding = 1;

while(padding <= 2) {

if(pos < 8) {

plain[pos++] = (byte)(rand() & 0xFF);

padding++;

}

if(pos == 8)

encrypt8Bytes();

}

int i = offset;

while(len > 0) {

if(pos < 8) {

plain[pos++] = in[i++];

len--;

}

if(pos == 8)

encrypt8Bytes();

}

padding = 1;

while(padding <= 7) {

if(pos < 8) {

plain[pos++] = 0x0;

padding++;

}

if(pos == 8)

encrypt8Bytes();

}

return out;

}

public byte[] encrypt(byte[] in, byte[] k) {

return encrypt(in, 0, in.length, k);

}

private byte[] encipher(byte[] in) {

int loop = 0x10;

long y = getUnsignedInt(in, 0, 4);

long z = getUnsignedInt(in, 4, 4);

long a = getUnsignedInt(key, 0, 4);

long b = getUnsignedInt(key, 4, 4);

long c = getUnsignedInt(key, 8, 4);

long d = getUnsignedInt(key, 12, 4);

long sum = 0;

long delta = 0x9E3779B9;

delta &= 0xFFFFFFFFL;

while (loop-- > 0) {

sum += delta;

sum &= 0xFFFFFFFFL;

y += ((z << 4) + a) ^ (z + sum) ^ ((z >>> 5) + b);

y &= 0xFFFFFFFFL;

z += ((y << 4) + c) ^ (y + sum) ^ ((y >>> 5) + d);

z &= 0xFFFFFFFFL;

}

baos.reset();

writeInt((int)y);

writeInt((int)z);

return baos.toByteArray();

}

private byte[] decipher(byte[] in, int offset) {

int loop = 0x10;

long y = getUnsignedInt(in, offset, 4);

long z = getUnsignedInt(in, offset + 4, 4);

long a = getUnsignedInt(key, 0, 4);

long b = getUnsignedInt(key, 4, 4);

long c = getUnsignedInt(key, 8, 4);

long d = getUnsignedInt(key, 12, 4);

long sum = 0xE3779B90;

sum &= 0xFFFFFFFFL;

long delta = 0x9E3779B9;

delta &= 0xFFFFFFFFL;

while(loop-- > 0) {

z -= ((y << 4) + c) ^ (y + sum) ^ ((y >>> 5) + d);

z &= 0xFFFFFFFFL;

y -= ((z << 4) + a) ^ (z + sum) ^ ((z >>> 5) + b);

y &= 0xFFFFFFFFL;

sum -= delta;

sum &= 0xFFFFFFFFL;

}

baos.reset();

writeInt((int)y);

writeInt((int)z);

return baos.toByteArray();

}

private void writeInt(int t) {

baos.write(t >>> 24);

baos.write(t >>> 16);

baos.write(t >>> 8);

baos.write(t);

}

private byte[] decipher(byte[] in) {

return decipher(in, 0);

}

private void encrypt8Bytes() {

for(pos = 0; pos < 8; pos++) {

if(header)

plain[pos] ^= prePlain[pos];

else

plain[pos] ^= out[preCrypt + pos];

}

byte[] crypted = encipher(plain);

System.arraycopy(crypted, 0, out, crypt, 8);

for(pos = 0; pos < 8; pos++)

out[crypt + pos] ^= prePlain[pos];

System.arraycopy(plain, 0, prePlain, 0, 8);

preCrypt = crypt;

crypt += 8;

pos = 0;

header = false;

}

private boolean decrypt8Bytes(byte[] in , int offset, int len) {

for(pos = 0; pos < 8; pos++) {

if(contextStart + pos >= len)

return true;

prePlain[pos] ^= in[offset + crypt + pos];

}

prePlain = decipher(prePlain);

if(prePlain == null)

return false;

contextStart += 8;

crypt += 8;

pos = 0;

return true;

}

private int rand() {

return random.nextInt();

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值