
java算法如下,可独立运行。怎奈小弟才疏学浅,有一段转换byte数组没看懂,哪位大侠能帮忙写个python版本,感激不尽~
package com.bmcc.service.pub.util; /** * Tea算法 * KEY为16字节,应为包含4个int型数的int[],一个int为4个字节 * 加密解密轮数应为8的倍数,推荐加密轮数为64轮 **/ public class Tea { private int[] KEY = new int[] { //加密解密所用的KEY 1, 2, 3, 4 }; private String separatoradd = "0"; //加密字符串分隔符"+" private String separatordel = "1"; //加密字符串分隔符"-" //加密 private byte[] encrypt( byte[] content, int offset, int[] key, int times) { //times为加密轮数 int[] tempInt = byteToInt(content, offset); int y = tempInt[0], z = tempInt[1], sum = 0, i; int delta = 0x9e3779b9; //这是算法标准给的值 int a = key[0], b = key[1], c = key[2], d = key[3]; for (i = 0; i < times; i++) { sum += delta; y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); } tempInt[0] = y; tempInt[1] = z; return intToByte(tempInt, 0); } //解密 private byte[] decrypt( byte[] encryptContent, int offset, int[] key, int times) { int[] tempInt = byteToInt(encryptContent, offset); int y = tempInt[0], z = tempInt[1], sum = 0xC6EF3720, i; int delta = 0x9e3779b9; //这是算法标准给的值 int a = key[0], b = key[1], c = key[2], d = key[3]; for (i = 0; i < times; i++) { z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); sum -= delta; } tempInt[0] = y; tempInt[1] = z; return intToByte(tempInt, 0); } //byte[]型数据转成int[]型数据 private int[] byteToInt(byte[] content, int offset) { int[] result = new int[content.length >> 2]; for (int i = 0, j = offset; j < content.length; i++, j += 4) { result[i] = transform(content[j + 3]) | transform(content[j + 2]) << 8 | transform(content[j + 1]) << 16 | (int) content[j] << 24; } return result; } //int[]型数据转成byte[]型数据 private byte[] intToByte(int[] content, int offset) { byte[] result = new byte[content.length << 2]; for (int i = 0, j = offset; j < result.length; i++, j += 4) { result[j + 3] = (byte) (content[i] & 0xff); result[j + 2] = (byte) ((content[i] >> 8) & 0xff); result[j + 1] = (byte) ((content[i] >> 16) & 0xff); result[j] = (byte) ((content[i] >> 24) & 0xff); } return result; } //若某字节被解释成负的则需将其转成无符号正数 private int transform(byte temp) { int tempInt = (int) temp; if (tempInt < 0) { tempInt += 256; } return tempInt; } // 通过TEA算法加密信息 public String encryptByTea(String info) { byte[] temp = info.getBytes(); int n = 8 - temp.length % 8; //若temp的位数不足8的倍数,需要填充的位数 byte[] encryptStr = new byte[temp.length + n]; encryptStr[0] = (byte) n; System.arraycopy(temp, 0, encryptStr, n, temp.length); byte[] result = new byte[encryptStr.length]; for (int offset = 0; offset < result.length; offset += 8) { byte[] tempEncrpt = encrypt(encryptStr, offset, KEY, 32); System.arraycopy(tempEncrpt, 0, result, offset, 8); } String tmp = encryptTwo(result); // for (int i = 0; i < result.length; i++) { // tmp = tmp + result[i] + this.separator; // } return tmp; } private String encryptTwo(byte[] source) { String all = ""; for (int i = 0; i < source.length; i++) { String tmp = this.separatoradd; int s = source[i]; if (s < 0) { s = ~s + 1; tmp = this.separatordel; } String res = Integer.toHexString(s); if (res.length() == 1) res = "0" + res; all = all + res + tmp; } return all; } public byte[] decryptTwo(String res) { int k = 0; byte[] result = new byte[res.length() / 3]; for (int i = 0, j = 3; i < res.length(); i = i + 3, j= i + 3) { String tmp = res.substring(i, j); if (this.separatoradd.charAt(0) == tmp.charAt(2)) result[k++] = Byte.parseByte(tmp.substring(0, 2),16); else if (this.separatordel.charAt(0) == tmp.charAt(2)) result[k++] = Byte.parseByte("-" + tmp.substring(0, 2),16); } return result; } // 通过TEA算法解密信息 public String decryptByTea(String info) { byte[] secretInfo = this.decryptTwo(info); byte[] decryptStr = null; byte[] tempDecrypt = new byte[secretInfo.length]; for (int offset = 0; offset < secretInfo.length; offset += 8) { decryptStr = decrypt(secretInfo, offset, KEY, 32); System.arraycopy(decryptStr, 0, tempDecrypt, offset, 8); } int n = tempDecrypt[0]; return new String(tempDecrypt, n, decryptStr.length - n); } public static void main(String[] args) { Tea tea = new Tea(); String src ="abcd1234"; String tmp = tea.encryptByTea(src); String result = tea.decryptByTea("2700304515a02c16411f06e14f17b14e16401c01c0591390"); System.out.print("原数据:"); System.out.println(src); System.out.print("加密后的数据:"); System.out.println(tmp); System.out.print("解密后的数据:"); System.out.println(result); } } 1 copyangle OP 主要是这一段不明白,求解 // 通过TEA算法加密信息 public String encryptByTea(String info) { byte[] temp = info.getBytes(); int n = 8 - temp.length % 8; //若temp的位数不足8的倍数,需要填充的位数 byte[] encryptStr = new byte[temp.length + n]; encryptStr[0] = (byte) n; System.arraycopy(temp, 0, encryptStr, n, temp.length); byte[] result = new byte[encryptStr.length]; for (int offset = 0; offset < result.length; offset += 8) { byte[] tempEncrpt = encrypt(encryptStr, offset, KEY, 32); System.arraycopy(tempEncrpt, 0, result, offset, 8); } String tmp = encryptTwo(result); // for (int i = 0; i < result.length; i++) { // tmp = tmp + result[i] + this.separator; // } return tmp; } |
2 zhantss 2015-07-30 11:46:55 +08:00 for循环前的转换? 获取输入字符的byte数组 获取填充位数n(<8) 新的byte数组第一个位置 放填充数n(<8所以byte足够表示) 然后从第n(填充位)开始放原有temp的内容(长度正好) for开始就是加密的过程了 |
4 zhantss 2015-07-31 10:38:56 +08:00 @copyangle 有点复杂 建议你看一下资料 python 是动态类型 一般情况下type(target) 可以看target的类型 python2 中用encode之后type()还是得到str类型 (你可以试一下help(bytes)出来的还是str) python3 中这样写就好了 s = 'test' bs = bytes(s, encoding='[你的字符串编码类型/文件标注编码类型]') 或者bs = s.encode('[你的字符串编码类型/文件标注编码类型]') 这时候type(bs)得到的是bytes类型 python2 中用第二种写法就好了, 第一种一般需要判断一下,但是你看到的类型还是str,有点难理解就是了,用还是可以用,稍稍有些不同 |