SM3代码(Java&&TS)

java

public class SM3Util {

    // 常量
    private static final int[] Tj = { 0x79cc4519, 0x7a879d8a };

    private SM3Util() {

    }

    /**
     * 左移函数
     * 
     * @param x
     * @param n
     * @return
     */
    private static int rotateLeft(int x, int n, int k) {
        return (x << n) | (x >>> k);
    }

    /**
     * P1(X) = X ⊕ (X ≪ 15) ⊕ (X ≪ 23)
     * 
     * @param X
     * @return
     */
    private static int p1(int X) {
        return X ^ rotateLeft(X, 15, 17) ^ rotateLeft(X, 23, 9);
    }

    /**
     * 数据填充
     * 
     * @param entity
     */
    private static byte[] padding(byte[] message) {

        int length = message.length;
        // 数据长度*8 得到实际的数据长度
        long datalength = length << 3;
        // 获取数据偏移
        int l = length & 63;

        // 补0的大小 k ≡ 448 - l - 1
        int padd = l > 55 ? 128 - l : 64 - l;

        // (64 - length) (二进制)
        byte[] paddArr = new byte[padd];
        paddArr[0] = (byte) 0x80;
        int k = padd - 8;
        for (int i = 1; i < k; i++) {
            paddArr[i] = 0x0;
        }
        for (int i = 0; i < 8; i++) {
            paddArr[i + k] = (byte) ((datalength >>> ((7 - i) << 3)) & 0xff);
        }
        byte[] result = new byte[length + padd];

        System.arraycopy(message, 0, result, 0, length);
        System.arraycopy(paddArr, 0, result, length, padd);

        return result;
    }

    /**
     * 处理数据
     * 
     * @param entity
     * @return
     */
    public static byte[] hash(byte[] message) {
        // 初始化参数
        int[] IV = { 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d,
                0xb0fb0e4e };

        // 遍历的长度
        long forlength = message.length >> 6;
        byte[] handByte = new byte[64];
        int[] groupbyA = new int[68];

        for (int index = 0; index < forlength; index++) {

            // 数组复制
            System.arraycopy(message, index << 6, handByte, 0, 64);

            // 处理数据
            // a)将消息分组B(i)划分为16个字W0, W1, · · · , W15。
            for (int i = 0; i < 64; i += 4) {
                groupbyA[i >> 2] = (handByte[i] & 0xff) << 24 | (handByte[i + 1] & 0xff) << 16
                        | (handByte[i + 2] & 0xff) << 8 | handByte[i + 3] & 0xff;
            }

            int a = IV[0];
            int b = IV[1];
            int c = IV[2];
            int d = IV[3];
            int e = IV[4];
            int f = IV[5];
            int g = IV[6];
            int h = IV[7];
            int ss1;
            int ss2;
            int tt1;
            int tt2;
            int j = 0;
            for (; j < 52; j++) {
                groupbyA[j + 16] = p1(groupbyA[j] ^ groupbyA[j + 7] ^ rotateLeft(groupbyA[j + 13], 15, 17))
                        ^ rotateLeft(groupbyA[j + 3], 7, 25) ^ groupbyA[j + 10];

                ss1 = rotateLeft((rotateLeft(a, 12, 20) + e + rotateLeft(Tj[j < 16 ? 0 : 1], j, 32 - j)), 7, 25);
                ss2 = ss1 ^ rotateLeft(a, 12, 20);

                if (j < 16) {
                    tt1 = (a ^ b ^ c) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
                    tt2 = (e ^ f ^ g) + h + ss1 + groupbyA[j];
                } else {
                    tt1 = ((a & b) | (a & c) | (b & c)) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
                    tt2 = ((e & f) | (~e & g)) + h + ss1 + groupbyA[j];
                }

                d = c;
                c = rotateLeft(b, 9, 23);
                b = a;
                a = tt1;
                h = g;
                g = rotateLeft(f, 19, 13);
                f = e;
                e = tt2 ^ rotateLeft(tt2, 9, 23) ^ rotateLeft(tt2, 17, 15);

            }

            for (; j < 64; j++) {

                ss1 = rotateLeft((rotateLeft(a, 12, 20) + e + rotateLeft(Tj[j < 16 ? 0 : 1], j, 32 - j)), 7, 25);
                ss2 = ss1 ^ rotateLeft(a, 12, 20);
                tt1 = ((a & b) | (a & c) | (b & c)) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
                tt2 = ((e & f) | (~e & g)) + h + ss1 + groupbyA[j];

                d = c;
                c = rotateLeft(b, 9, 23);
                b = a;
                a = tt1;
                h = g;
                g = rotateLeft(f, 19, 13);
                f = e;
                e = tt2 ^ rotateLeft(tt2, 9, 23) ^ rotateLeft(tt2, 17, 15);

            }

            IV[0] ^= a;
            IV[1] ^= b;
            IV[2] ^= c;
            IV[3] ^= d;
            IV[4] ^= e;
            IV[5] ^= f;
            IV[6] ^= g;
            IV[7] ^= h;

        }

        byte[] result = new byte[32];
        for (int i = 0; i < 8; i++) {
            intToByteArray(IV[i], result, i << 2);
        }
        return result;
    }

    /**
     * int转byte数组
     * 
     * @param n      数字
     * @param b      byte数组
     * @param offset 偏移量
     */
    private static void intToByteArray(int n, byte[] b, int offset) {
        b[offset] = (byte) (n >>> 24);
        b[offset + 1] = (byte) (n >>> 16);
        b[offset + 2] = (byte) (n >>> 8);
        b[offset + 3] = (byte) n;
    }

    /**
     * 加密
     *
     * @return
     */
    public static String encryption(Object object) {

        byte[] byteArray = null;
        if (object instanceof Number) {
            byteArray = object.toString().getBytes(StandardCharsets.UTF_8);

        } else if (object instanceof File) {

            try {
                byteArray = Files.readAllBytes(((File) object).toPath());
            } catch (IOException e) {
                e.printStackTrace();
            }

        } else if (object instanceof byte[]) {
            byteArray = (byte[]) object;
        } else if (object instanceof String) {
            byteArray = ((String) object).getBytes(StandardCharsets.UTF_8);

        }
        return encryption(byteArray);

    }

    /**
     * 加密数据
     * 
     * @param byteArray
     * @return
     */
    public static String encryption(String byteArray) {
        return encryption(byteArray.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 加密数据
     * 
     * @param byteArray
     * @return
     */
    public static String encryption(byte[] byteArray) {

        try {
            if (byteArray != null) {
                return ArrayUtils.bytesToHex(hash(padding(byteArray)));
            }
        } catch (Exception e) {
            e.printStackTrace();

        }
        return "";

    }

    public static void main(String[] args) {
        System.err.println(SM3Util.encryption("1234567"));
    }
}

TS

export class SM3Utils {


    /**
   * @param workerId
   *                     工作机器ID
   * @param datacenterId
   *                     序列号
   */
    constructor() {
    }

    // 常量
    private static Tj: number[] = [0x79cc4519, 0x7a879d8a];


    /**
     * 左移函数
     * 
     * @param x
     * @param n
     * @return
     */
    private static rotateLeft(x: number, n: number, k: number): number {
        return (x << n) | (x >>> k);
    }

    /**
     * P1(X) = X ⊕ (X ≪ 15) ⊕ (X ≪ 23)
     * 
     * @param X
     * @return
     */
    private static p1(X: number): number {
        return X ^ this.rotateLeft(X, 15, 17) ^ this.rotateLeft(X, 23, 9);
    }


    /**
     * 数据填充
     * 
     * @param entity
     */
    private static padding(message: Int8Array): Int8Array {
        const length: number = message.length;
        // 数据长度*8 得到实际的数据长度
        const datalength: bigint = BigInt(length) << BigInt(3);
        // 获取数据偏移
        const l: number = length & 63;

        // 补0的大小 k ≡ 448 - l - 1
        const padd: number = l > 55 ? 128 - l : 64 - l;

        // (64 - length) (二进制)
        const paddArr: Int8Array = new Int8Array(padd);
        paddArr[0] = 0x80;
        const k: number = padd - 8;
        for (let i = 1; i < k; i++) {
            paddArr[i] = 0x0;
        }
        for (let i = 0; i < 8; i++) {
            paddArr[i + k] = Number((datalength >> BigInt((7 - i) << 3)) & BigInt(0xff));
        }
        const result: Int8Array = new Int8Array(length + padd);

        result.set(message);
        result.set(paddArr, length);

        return result;
    }

    /**
     * 处理数据
     * 
     * @param entity
     * @return
     */
    public static hash(message: Int8Array): Int8Array {
        const IV: number[] = [0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e];

        const forlength: bigint = BigInt(message.length) >> BigInt(6);
        const handByte: Int8Array = new Int8Array(64);
        const groupbyA: number[] = new Array(68);



        for (let index = 0n; index < forlength; index++) {

            handByte.set(message.subarray(Number(index << BigInt(6)), Number(index << BigInt(6)) + 64));


            for (let i = 0; i < 64; i += 4) {

                groupbyA[i >> 2] = (handByte[i] & 0xff) << 24 | (handByte[i + 1] & 0xff) << 16
                    | (handByte[i + 2] & 0xff) << 8 | handByte[i + 3] & 0xff;
            }

            let a: number = IV[0];
            let b: number = IV[1];
            let c: number = IV[2];
            let d: number = IV[3];
            let e: number = IV[4];
            let f: number = IV[5];
            let g: number = IV[6];
            let h: number = IV[7];

            let ss1: number, ss2: number, tt1: number, tt2: number;
            let j: number = 0;
            for (; j < 52; j++) {
                groupbyA[j + 16] = this.p1(groupbyA[j] ^ groupbyA[j + 7] ^ this.rotateLeft(groupbyA[j + 13], 15, 17)) ^ this.rotateLeft(groupbyA[j + 3], 7, 25) ^ groupbyA[j + 10];

                ss1 = this.rotateLeft((this.rotateLeft(a, 12, 20) + e + this.rotateLeft(this.Tj[j < 16 ? 0 : 1], j, 32 - j)), 7, 25);
                ss2 = ss1 ^ this.rotateLeft(a, 12, 20);

                if (j < 16) {
                    tt1 = (a ^ b ^ c) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
                    tt2 = (e ^ f ^ g) + h + ss1 + groupbyA[j];
                } else {
                    tt1 = ((a & b) | (a & c) | (b & c)) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
                    tt2 = ((e & f) | (~e & g)) + h + ss1 + groupbyA[j];
                }

                d = c;
                c = this.rotateLeft(b, 9, 23);
                b = a;
                a = tt1;
                h = g;
                g = this.rotateLeft(f, 19, 13);
                f = e;
                e = tt2 ^ this.rotateLeft(tt2, 9, 23) ^ this.rotateLeft(tt2, 17, 15);
            }

            for (; j < 64; j++) {
                ss1 = this.rotateLeft((this.rotateLeft(a, 12, 20) + e + this.rotateLeft(this.Tj[j < 16 ? 0 : 1], j, 32 - j)), 7, 25);
                ss2 = ss1 ^ this.rotateLeft(a, 12, 20);
                tt1 = ((a & b) | (a & c) | (b & c)) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
                tt2 = ((e & f) | (~e & g)) + h + ss1 + groupbyA[j];

                d = c;
                c = this.rotateLeft(b, 9, 23);
                b = a;
                a = tt1;
                h = g;
                g = this.rotateLeft(f, 19, 13);
                f = e;
                e = tt2 ^ this.rotateLeft(tt2, 9, 23) ^ this.rotateLeft(tt2, 17, 15);
            }

            IV[0] ^= a;
            IV[1] ^= b;
            IV[2] ^= c;
            IV[3] ^= d;
            IV[4] ^= e;
            IV[5] ^= f;
            IV[6] ^= g;
            IV[7] ^= h;


        }



        const result: Int8Array = new Int8Array(32);
        for (let i = 0; i < 8; i++) {
            this.intToByteArray(IV[i], result, i << 2);
        }
        return result;
    }

    /**
     * 转数据
     * @param value 
     * @param byteArray 
     * @param offset 
     */
    private static intToByteArray(value: number, byteArray: Int8Array, offset: number) {
        byteArray[offset] = (value >>> 24) & 0xff;
        byteArray[offset + 1] = (value >>> 16) & 0xff;
        byteArray[offset + 2] = (value >>> 8) & 0xff;
        byteArray[offset + 3] = value & 0xff;
    }


    /**
     * 加密
     * @param object 
     * @returns 
     */
    public static encryption(object: any): string {

        let byteArray: Int8Array | null = null;

        if (typeof object === 'number' || typeof object === 'string') {
            byteArray = new Int8Array(new TextEncoder().encode(object.toString()));
        } else if (object instanceof File) {


            const reader = new FileReader();
            reader.readAsArrayBuffer(object);
            byteArray = new Int8Array(reader.result as ArrayBuffer);

        } else if (Array.isArray(object) && object.every((el) => typeof el === 'number')) {
            byteArray = new Int8Array(object);
        }

        if (byteArray) {

            return ArrayUtils.bytesToHex(this.hash(this.padding(byteArray)));
        }

        return '';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风殇无极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值