You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					196 lines
				
				6.6 KiB
			
		
		
			
		
	
	
					196 lines
				
				6.6 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								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);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 |