package com.ynxbd.common.helper.common; import org.apache.commons.codec.binary.Base64; /** * Tea算法 * 每次操作可以处理8个字节数据 * KEY为16字节,应为包含4个int型数的int[],一个int为4个字节 * 加密解密轮数应为8的倍数,推荐加密轮数为64轮 */ public class TeaHelper { // 加密解密所用的4组KEY private final static int[] KEY = new int[]{ 0x789f5555, 0xf68bd5a4, 0x81963fff, 0x458fac58 }; /** * @param content 加密内容 * @param offset 位数(32) * @param key 加密key * @param roundS 加密轮数 * @return 返回字节数据 */ private static byte[] encrypt(byte[] content, int offset, int[] key, int roundS) { 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 < roundS; 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); } /** * 解密算法 * * @param encryptContent 需要解密的内容 * @param offset 位数(32) * @param key 密钥 * @param rounds 加密次数 * @return 解密数据 */ private static byte[] decrypt(byte[] encryptContent, int offset, int[] key, int rounds) { int[] tempInt = byteToInt(encryptContent, 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]; if (rounds == 32) { sum = 0xC6EF3720; /* delta << 5*/ } else if (rounds == 16) { sum = 0xE3779B90; /* delta << 4*/ } else { sum = delta * rounds; } for (i = 0; i < rounds; 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 * * @param content 内容 * @param offset 位数(32) * @return byte */ private static int[] byteToInt(byte[] content, int offset) { //除以2的n次方 == 右移n位 即 content.length / 4 == content.length >> 2 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 * * @param content 内容 * @param offset 位数(32) * @return byte */ private static byte[] intToByte(int[] content, int offset) { // 乘以2的n次方 == 左移n位 即 content.length * 4 == content.length << 2 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 static int transform(byte temp) { int tempInt = temp; if (tempInt < 0) { tempInt += 256; } return tempInt; } /** * TEA算法加密信息 * * @param info 被加密的信息 * @return 加密后的信息 */ public static String encryptByTea(String info) { try { byte[] temp = info.getBytes(); // 若temp的位数不足8的倍数,需要填充的位数 int n = 8 - temp.length % 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[] temEncrypt = TeaHelper.encrypt(encryptStr, offset, KEY, 32); System.arraycopy(temEncrypt, 0, result, offset, 8); } return new Base64().encodeToString(result); } catch (Exception e) { e.printStackTrace(); return null; } } /** * TEA算法解密信息 * * @param decStr 被解密的字符串 * @return 解密后的字符串 */ public static String decryptByTea(String decStr) { if (decStr == null) { return null; } else { if ("".equals(decStr.trim())) { return null; } } try { //先用base64解密 byte[] secretInfo = new Base64().decode(decStr); byte[] decryptStr = null; byte[] tempDecrypt = new byte[secretInfo.length]; for (int offset = 0; offset < secretInfo.length; offset += 8) { decryptStr = TeaHelper.decrypt(secretInfo, offset, KEY, 32); System.arraycopy(decryptStr, 0, tempDecrypt, offset, 8); } int n = tempDecrypt[0]; return new String(tempDecrypt, n, decryptStr.length - n); } catch (Exception e) { e.printStackTrace(); return null; } } public static void main(String[] args) { String info = "{" + "'name':'xyz'," + "'age':'16'," + "'gender':'male'" + "}"; System.out.println("原数据:" + info); System.out.println("开始时间:" + System.currentTimeMillis()); String base64 = encryptByTea(info); System.out.println("加密后的数据:"); System.out.println(base64); String decryptInfo = decryptByTea(base64); System.out.println("结束时间:" + System.currentTimeMillis()); System.out.print("解密后的数据:"); System.out.println(decryptInfo); } }