MD4.java 6.29 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.day.text;

public class MD4 {
    private static final byte[] PADDING = new byte[]{-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    private static final int S11 = 3;
    private static final int S12 = 7;
    private static final int S13 = 11;
    private static final int S14 = 19;
    private static final int S21 = 3;
    private static final int S22 = 5;
    private static final int S23 = 9;
    private static final int S24 = 13;
    private static final int S31 = 3;
    private static final int S32 = 9;
    private static final int S33 = 11;
    private static final int S34 = 15;
    private int[] state = new int[4];
    private int[] count = new int[2];
    private byte[] buffer = new byte[64];

    public MD4() {
        this.init();
    }

    private void init() {
        this.count[1] = 0;
        this.count[0] = 0;
        this.state[0] = 1732584193;
        this.state[1] = -271733879;
        this.state[2] = -1732584194;
        this.state[3] = 271733878;
    }

    public void update(byte[] input, int off, int len) {
        int i;
        int index = this.count[0] >> 3 & 63;
        int bitlen = len << 3;
        this.count[0] = this.count[0] + bitlen;
        if (this.count[0] < bitlen) {
            int[] arrn = this.count;
            arrn[1] = arrn[1] + 1;
        }
        int[] arrn = this.count;
        arrn[1] = arrn[1] + (len >> 29);
        int partlen = 64 - index;
        if (len >= partlen) {
            System.arraycopy(input, off, this.buffer, index, partlen);
            this.transform(this.buffer, 0);
            i = partlen;
            while (i + 63 < len) {
                this.transform(input, off + i);
                i += 64;
            }
            index = 0;
        } else {
            i = 0;
        }
        System.arraycopy(input, off + i, this.buffer, index, len - i);
    }

    public byte[] finish() {
        byte[] digest = new byte[16];
        byte[] bits = new byte[8];
        MD4.encode(this.count, bits, 0, bits.length);
        int index = this.count[0] >> 3 & 63;
        int padlen = index < 56 ? 56 - index : 120 - index;
        this.update(PADDING, 0, padlen);
        this.update(bits, 0, bits.length);
        MD4.encode(this.state, digest, 0, digest.length);
        return digest;
    }

    private void transform(byte[] block, int offset) {
        int a = this.state[0];
        int b = this.state[1];
        int c = this.state[2];
        int d = this.state[3];
        int[] x = new int[16];
        MD4.decode(block, offset, 64, x);
        a = MD4.FF(a, b, c, d, x[0], 3);
        d = MD4.FF(d, a, b, c, x[1], 7);
        c = MD4.FF(c, d, a, b, x[2], 11);
        b = MD4.FF(b, c, d, a, x[3], 19);
        a = MD4.FF(a, b, c, d, x[4], 3);
        d = MD4.FF(d, a, b, c, x[5], 7);
        c = MD4.FF(c, d, a, b, x[6], 11);
        b = MD4.FF(b, c, d, a, x[7], 19);
        a = MD4.FF(a, b, c, d, x[8], 3);
        d = MD4.FF(d, a, b, c, x[9], 7);
        c = MD4.FF(c, d, a, b, x[10], 11);
        b = MD4.FF(b, c, d, a, x[11], 19);
        a = MD4.FF(a, b, c, d, x[12], 3);
        d = MD4.FF(d, a, b, c, x[13], 7);
        c = MD4.FF(c, d, a, b, x[14], 11);
        b = MD4.FF(b, c, d, a, x[15], 19);
        a = MD4.GG(a, b, c, d, x[0], 3);
        d = MD4.GG(d, a, b, c, x[4], 5);
        c = MD4.GG(c, d, a, b, x[8], 9);
        b = MD4.GG(b, c, d, a, x[12], 13);
        a = MD4.GG(a, b, c, d, x[1], 3);
        d = MD4.GG(d, a, b, c, x[5], 5);
        c = MD4.GG(c, d, a, b, x[9], 9);
        b = MD4.GG(b, c, d, a, x[13], 13);
        a = MD4.GG(a, b, c, d, x[2], 3);
        d = MD4.GG(d, a, b, c, x[6], 5);
        c = MD4.GG(c, d, a, b, x[10], 9);
        b = MD4.GG(b, c, d, a, x[14], 13);
        a = MD4.GG(a, b, c, d, x[3], 3);
        d = MD4.GG(d, a, b, c, x[7], 5);
        c = MD4.GG(c, d, a, b, x[11], 9);
        b = MD4.GG(b, c, d, a, x[15], 13);
        a = MD4.HH(a, b, c, d, x[0], 3);
        d = MD4.HH(d, a, b, c, x[8], 9);
        c = MD4.HH(c, d, a, b, x[4], 11);
        b = MD4.HH(b, c, d, a, x[12], 15);
        a = MD4.HH(a, b, c, d, x[2], 3);
        d = MD4.HH(d, a, b, c, x[10], 9);
        c = MD4.HH(c, d, a, b, x[6], 11);
        b = MD4.HH(b, c, d, a, x[14], 15);
        a = MD4.HH(a, b, c, d, x[1], 3);
        d = MD4.HH(d, a, b, c, x[9], 9);
        c = MD4.HH(c, d, a, b, x[5], 11);
        b = MD4.HH(b, c, d, a, x[13], 15);
        a = MD4.HH(a, b, c, d, x[3], 3);
        d = MD4.HH(d, a, b, c, x[11], 9);
        c = MD4.HH(c, d, a, b, x[7], 11);
        b = MD4.HH(b, c, d, a, x[15], 15);
        int[] arrn = this.state;
        arrn[0] = arrn[0] + a;
        int[] arrn2 = this.state;
        arrn2[1] = arrn2[1] + b;
        int[] arrn3 = this.state;
        arrn3[2] = arrn3[2] + c;
        int[] arrn4 = this.state;
        arrn4[3] = arrn4[3] + d;
    }

    private static void encode(int[] input, byte[] output, int off, int len) {
        int i = 0;
        for (int j = off; j < off + len; j += 4) {
            output[j] = (byte)(input[i] & 255);
            output[j + 1] = (byte)(input[i] >> 8 & 255);
            output[j + 2] = (byte)(input[i] >> 16 & 255);
            output[j + 3] = (byte)(input[i] >> 24 & 255);
            ++i;
        }
    }

    private static void decode(byte[] input, int off, int len, int[] output) {
        int i = 0;
        for (int j = off; j < off + len; j += 4) {
            int ch1 = input[j] & 255;
            int ch2 = input[j + 1] & 255;
            int ch3 = input[j + 2] & 255;
            int ch4 = input[j + 3] & 255;
            output[i] = ch1 | ch2 << 8 | ch3 << 16 | ch4 << 24;
            ++i;
        }
    }

    private static int FF(int a, int b, int c, int d, int x, int s) {
        return a << s | (a += (b & c | ~ b & d) + x) >>> 32 - s;
    }

    private static int GG(int a, int b, int c, int d, int x, int s) {
        return a << s | (a += (b & c | b & d | c & d) + x + 1518500249) >>> 32 - s;
    }

    private static int HH(int a, int b, int c, int d, int x, int s) {
        return a << s | (a += (b ^ c ^ d) + x + 1859775393) >>> 32 - s;
    }

    public static byte[] digest(byte[] input) {
        MD4 md4 = new MD4();
        md4.update(input, 0, input.length);
        return md4.finish();
    }
}