tea加解密工具类

这是一个实现了TEA(Tiny Encryption Algorithm)加密算法的Java类,包括加密和解密方法。类中设置了密钥和加密轮数,并使用了内部的TeaUtils进行实际的加密和解密操作。加密过程中,数据被分组处理,根据余数进行填充以达到8字节的倍数,解密过程则相反。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.common.utils;

import java.io.UnsupportedEncodingException;

public class TeaUtils {
    
    public static byte[] encrypt(byte[] data, byte[] key) {
        int data_len = data.length; // 数据的长度
        if (data_len == 0) {
            return new byte[] {};
        }
        TeaUtils t = new TeaUtils();
        if (!t.setKey(key)) {
            return new byte[] {};
        }
        
        int group_len = 8;
        int residues = data_len % group_len; // 余数
        int dlen = data_len - residues;
        
        // 用于储存加密的密文,第一字节为余数的大小
        int result_len = data_len;
        if (residues > 0) {
            result_len += group_len - residues;
        }
        byte[] result = new byte[result_len];
        //result[0] = (byte)residues;
        
        byte[] plain = new byte[group_len];
        byte[] enc = new byte[group_len];
        
        for (int i = 0; i < dlen; i += group_len) {
            for (int j = 0; j < group_len; j++) {
                plain[j] = data[i + j];
            }
            enc = t.encrypt_group(plain);
            for (int k = 0; k < group_len; k++) {
                //result[i + k + 1] = enc[k];
                result[i + k ] = enc[k];
            }
        }
        if (residues > 0) {
            for (int j = 0; j < residues; j++) {
                plain[j] = data[dlen + j];
            }
            int padding = group_len - residues;
            for (int j = 0; j < padding; j++) {
                plain[residues + j] = (byte)0x00;
            }
            enc = t.encrypt_group(plain);
            for (int k = 0; k < group_len; k++) {
                //result[dlen + k + 1] = enc[k];
                result[dlen + k] = enc[k];
            }
        }
        return result;
    }

    
    public static byte[] decrypt(byte[] data, byte[] key) {
        int group_len = 8;

        TeaUtils t = new TeaUtils();
        if (!t.setKey(key)) {
            return new byte[] {};
        }
        //int data_len = data.length - 1, dlen; // 数据的长度
        int data_len = data.length, dlen; // 数据的长度
        dlen = data_len;
        //byte[] result = new byte[dlen + residues];
        byte[] result = new byte[dlen];
        
        byte[] dec = new byte[group_len];
        byte[] enc = new byte[group_len];
        for (int i = 0; i < dlen; i += group_len) {
            for (int j = 0; j < group_len; j++) {
                //enc[j] = data[i + j + 1];
                enc[j] = data[i + j];
            }
            dec = t.decrypt_group(enc);
            for (int k = 0; k < group_len; k++) {
                result[i + k] = dec[k];
            }
        }
        return result;
    }

    
    /**
     * 设置密钥
     * @param k 密钥
     * @return 密钥长度为16个byte时, 设置密钥并返回true,否则返回false
     */
    public boolean setKey(byte[] k) {
        if(k==null){
            k = //你的密钥
        }
        if (k.length != 16) {
            return false;
        }
        k0 = bytes_to_uint32(new byte[] {k[0], k[1], k[2], k[3]});
        k1 = bytes_to_uint32(new byte[] {k[4], k[5], k[6], k[7]});
        k2 = bytes_to_uint32(new byte[] {k[8], k[9], k[10], k[11]});
        k3 = bytes_to_uint32(new byte[] {k[12], k[13], k[14], k[15]});
        return true;
    }
    
    /**
     * 设置加密的轮数,默认为32轮
     * @param loops 加密轮数
     * @return 轮数为16、32、64时,返回true,否则返回false
     */
    public boolean setLoops(int loops) {
        switch (loops) {
            case 16:
            case 32:
            case 64:
                this.loops = loops;
                return true;
        }
        return false;
    }
    
    private static long UINT32_MAX = 0xFFFFFFFFL;
    private static long BYTE_1 = 0xFFL;
    private static long BYTE_2 = 0xFF00L;
    private static long BYTE_3 = 0xFF0000L;
    private static long BYTE_4 = 0xFF000000L;
    
    private static long delta = 0x9E3779B9L;
    
    private static long k0;
    private static long k1;
    private static long k2;
    private static long k3;
    
    private static int loops = 32;
    
    /**
     * 加密一组明文
     * @param v 需要加密的明文
     * @return 返回密文
     */
   public static byte[] encrypt_group(byte[] v) {
        long v0 = bytes_to_uint32(new byte[] {v[0], v[1], v[2], v[3]});
        long v1 = bytes_to_uint32(new byte[] {v[4], v[5], v[6], v[7]});
        long sum = 0L;
        long v0_xor_1 = 0L, v0_xor_2 = 0L, v0_xor_3 = 0L;
        long v1_xor_1 = 0L, v1_xor_2 = 0L, v1_xor_3 = 0L;
        for (int i = 0; i < loops; i++) {
            sum = toUInt32(sum + delta);
            v0_xor_1 = toUInt32(toUInt32(v1 << 4) + k0);
            v0_xor_2 = toUInt32(v1 + sum);
            v0_xor_3 = toUInt32((v1 >> 5) + k1);
            v0 = toUInt32(  v0 + toUInt32(v0_xor_1 ^ v0_xor_2 ^ v0_xor_3)  );
            v1_xor_1 = toUInt32(toUInt32(v0 << 4) + k2);
            v1_xor_2 = toUInt32(v0 + sum);
            v1_xor_3 = toUInt32((v0 >> 5) + k3);
            v1 = toUInt32(  v1 + toUInt32(v1_xor_1 ^ v1_xor_2 ^ v1_xor_3)  );
        }
        byte[] b0 = long_to_bytes(v0, 4);
        byte[] b1 = long_to_bytes(v1, 4);
        return new byte[] {b0[0], b0[1], b0[2], b0[3], b1[0], b1[1], b1[2], b1[3]};
    }
    
    /**
     * 解密一组密文
     * @param v 要解密的密文
     * @return 返回明文
     */
   public static byte[] decrypt_group(byte[] v) {
        long v0 = bytes_to_uint32(new byte[] {v[0], v[1], v[2], v[3]});
        long v1 = bytes_to_uint32(new byte[] {v[4], v[5], v[6], v[7]});
        long sum = 0xC6EF3720L, tmp = 0L;
        for (int i = 0; i < loops; i++) {
            tmp = toUInt32(toUInt32(v0 << 4) + k2);
            v1 = toUInt32(  v1 - toUInt32(tmp ^  toUInt32(v0 + sum) ^ toUInt32((v0 >> 5) + k3))  );
            tmp = toUInt32(toUInt32(v1 << 4) + k0);
            v0 = toUInt32(  v0 - toUInt32(tmp ^  toUInt32(v1 + sum) ^ toUInt32((v1 >> 5) + k1))  );
            sum = toUInt32(sum - delta);
        }
        byte[] b0 = long_to_bytes(v0, 4);
        byte[] b1 = long_to_bytes(v1, 4);
        return new byte[] {b0[0], b0[1], b0[2], b0[3], b1[0], b1[1], b1[2], b1[3]};
    }
    
    
    /**
     * 将 long 类型的 n 转为 byte 数组,如果 len 为 4,则只返回低32位的4个byte
     * @param n 需要转换的long
     * @param len 若为4,则只返回低32位的4个byte,否则返回8个byte
     * @return 转换后byte数组
     */
    private static byte[] long_to_bytes(long n, int len) {
        byte a = (byte)((n & BYTE_4) >> 24);
        byte b = (byte)((n & BYTE_3) >> 16);
        byte c = (byte)((n & BYTE_2) >> 8);
        byte d = (byte)(n & BYTE_1);
        if (len == 4) {
            return new byte[] {a, b, c, d};
        }
        byte ha = (byte)(n >> 56);
        byte hb = (byte)((n >> 48) & BYTE_1);
        byte hc = (byte)((n >> 40) & BYTE_1);
        byte hd = (byte)((n >> 32) & BYTE_1);
        return new byte[] {ha, hb, hc, hd, a, b, c, d};
    }
    
    /**
     * 将4个byte转为 Unsigned Integer 32,以 long 形式返回
     * @param bs 需要转换的字节
     * @return 返回 long,高32位为0,低32位视为Unsigned Integer
     */
    private static long bytes_to_uint32(byte[] bs) {
        return ((bs[0]<<24) & BYTE_4) +
               ((bs[1]<<16) & BYTE_3) +
               ((bs[2]<<8)  & BYTE_2) +
               (bs[3] & BYTE_1);
    }
    
    /**
     * 将long的高32位清除,只保留低32位,低32位视为Unsigned Integer
     * @param n 需要清除的long
     * @return 返回高32位全为0的long
     */
    private static long toUInt32(long n) {
        return n & UINT32_MAX;
    }
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值