RIPEMD128.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Заготовка, показывающая некоторые возможности языка программирования и среды исполнения ПВТ-ОО.
    Вычисляет и выводит на консоль контрольную сумму по алгоритму RIPEMD-128 для некоторых примеров.

    Чтобы откомпилировать эту заготовку:
    1. Переместите папку ru.malik.elaborarer.avt.examples.ripemd128 в папку src.avt
    2. Переместите папку ru.malik.elaborarer.avt.testapp так, чтобы она находилась не в папке src.avt
    3. Компилируйте библиотеку avt-basic-core.ia-32e.microsoft-windows.console
*/

package ru.malik.elaborarer.avt.examples.ripemd128;

import avt.io.*;
import avtx.consoleapp.*;

public class RIPEMD128(ConsoleApp)
{
    public static final int4 INITIAL_VALUE = new int4 { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };

    public static char[] toCharArray(int4 hash) {
		char[] result = new char[32];
        for(int offset = 0, int i = 0; i < 16; i++)
        {
            int b = (hash[i >> 2] >> ((i & 3) << 3)) & 0xffi;
            result[offset++] = Char.toChar(b >> 4);
            result[offset++] = Char.toChar(b & 15);
        }
        return result;
    }

    public static int4 hash(int4 previous, byte[] src) { return hash(previous, src, 0, src == null ? 0 : src.length); }

    public static int4 hash(int4 previous, byte[] src, int offset, int length) {
        if(src == null)
        {
            throw new NullPointerException("аргумент src равен нулевой ссылке");
        }
        Array.checkBounds(src, offset, length);
		int ofs = offset;
		int lim = offset + length;
		int[] x = new int[16];
        int4 result = previous;
        boolean loop = true;
        do
        {
            for(int i = 0; i < 16; i++)
            {
                int m = 0;
                for(int j = 0; j < 32; j += 8)
                {
                    if(ofs >= offset && ofs < lim)
                    {
                        m |= (src[ofs++] & 0xffi) << j;
                    }
                    else if(ofs++ == lim)
                    {
                        m |= 0x80 << j;
                    }
                }
                x[i] = m;
            }
            if(ofs >= lim + 8 || ofs < 0)
            {
                long bitlen = (long) length << 3;
                x[14] = (int) bitlen;
                x[15] = (int) (bitlen >> 32);
                loop = false;
            }
            result = update(result, x);
        } while(loop);
		return result;
    }

    private static void computeAndPrintlnHash(PrintStream printer, String string) {
        printer.println(new StringBuilder() + "RIPEMD-128(\"" + string + "\") = " + toCharArray(hash(INITIAL_VALUE, string.toByteArray())));
    }

    private static int f(int x, int y, int z) { return x ^ y ^ z; }

    private static int g(int x, int y, int z) { return x & y | ~x & z; }

    private static int h(int x, int y, int z) { return (x | ~y) ^ z; }

    private static int i(int x, int y, int z) { return x & z | y & ~z; }

    private static int2 round1(int2 a, int2 b, int2 c, int2 d, int x1, int s1, int x2, int s2) {
        a += new int2 { f(b[0], c[0], d[0]) + x1, i(b[1], c[1], d[1]) + x2 } + new int2 { 0x00000000, 0x50a28be6 };
        return new int2 { Int.rotateLeft(a[0], s1), Int.rotateLeft(a[1], s2) };
    }

    private static int2 round2(int2 a, int2 b, int2 c, int2 d, int x1, int s1, int x2, int s2) {
        a += new int2 { g(b[0], c[0], d[0]) + x1, h(b[1], c[1], d[1]) + x2 } + new int2 { 0x5a827999, 0x5c4dd124 };
        return new int2 { Int.rotateLeft(a[0], s1), Int.rotateLeft(a[1], s2) };
    }

    private static int2 round3(int2 a, int2 b, int2 c, int2 d, int x1, int s1, int x2, int s2) {
        a += new int2 { h(b[0], c[0], d[0]) + x1, g(b[1], c[1], d[1]) + x2 } + new int2 { 0x6ed9eba1, 0x6d703ef3 };
        return new int2 { Int.rotateLeft(a[0], s1), Int.rotateLeft(a[1], s2) };
    }

    private static int2 round4(int2 a, int2 b, int2 c, int2 d, int x1, int s1, int x2, int s2) {
        a += new int2 { i(b[0], c[0], d[0]) + x1, f(b[1], c[1], d[1]) + x2 } + new int2 { 0x8f1bbcdc, 0x00000000 };
        return new int2 { Int.rotateLeft(a[0], s1), Int.rotateLeft(a[1], s2) };
    }

    private static int4 update(int4 previous, int[] x) {
		int buf;
		int2 a = new int2 { buf = previous[0], buf };
		int2 b = new int2 { buf = previous[1], buf };
		int2 c = new int2 { buf = previous[2], buf };
		int2 d = new int2 { buf = previous[3], buf };

		a = round1(a, b, c, d, x[ 0], 11, x[ 5],  8);
		d = round1(d, a, b, c, x[ 1], 14, x[14],  9);
		c = round1(c, d, a, b, x[ 2], 15, x[ 7],  9);
		b = round1(b, c, d, a, x[ 3], 12, x[ 0], 11);
		a = round1(a, b, c, d, x[ 4],  5, x[ 9], 13);
		d = round1(d, a, b, c, x[ 5],  8, x[ 2], 15);
		c = round1(c, d, a, b, x[ 6],  7, x[11], 15);
		b = round1(b, c, d, a, x[ 7],  9, x[ 4],  5);
		a = round1(a, b, c, d, x[ 8], 11, x[13],  7);
		d = round1(d, a, b, c, x[ 9], 13, x[ 6],  7);
		c = round1(c, d, a, b, x[10], 14, x[15],  8);
		b = round1(b, c, d, a, x[11], 15, x[ 8], 11);
		a = round1(a, b, c, d, x[12],  6, x[ 1], 14);
		d = round1(d, a, b, c, x[13],  7, x[10], 14);
		c = round1(c, d, a, b, x[14],  9, x[ 3], 12);
		b = round1(b, c, d, a, x[15],  8, x[12],  6);

		a = round2(a, b, c, d, x[ 7],  7, x[ 6],  9);
		d = round2(d, a, b, c, x[ 4],  6, x[11], 13);
		c = round2(c, d, a, b, x[13],  8, x[ 3], 15);
		b = round2(b, c, d, a, x[ 1], 13, x[ 7],  7);
		a = round2(a, b, c, d, x[10], 11, x[ 0], 12);
		d = round2(d, a, b, c, x[ 6],  9, x[13],  8);
		c = round2(c, d, a, b, x[15],  7, x[ 5],  9);
		b = round2(b, c, d, a, x[ 3], 15, x[10], 11);
		a = round2(a, b, c, d, x[12],  7, x[14],  7);
		d = round2(d, a, b, c, x[ 0], 12, x[15],  7);
		c = round2(c, d, a, b, x[ 9], 15, x[ 8], 12);
		b = round2(b, c, d, a, x[ 5],  9, x[12],  7);
		a = round2(a, b, c, d, x[ 2], 11, x[ 4],  6);
		d = round2(d, a, b, c, x[14],  7, x[ 9], 15);
		c = round2(c, d, a, b, x[11], 13, x[ 1], 13);
		b = round2(b, c, d, a, x[ 8], 12, x[ 2], 11);

		a = round3(a, b, c, d, x[ 3], 11, x[15],  9);
		d = round3(d, a, b, c, x[10], 13, x[ 5],  7);
		c = round3(c, d, a, b, x[14],  6, x[ 1], 15);
		b = round3(b, c, d, a, x[ 4],  7, x[ 3], 11);
		a = round3(a, b, c, d, x[ 9], 14, x[ 7],  8);
		d = round3(d, a, b, c, x[15],  9, x[14],  6);
		c = round3(c, d, a, b, x[ 8], 13, x[ 6],  6);
		b = round3(b, c, d, a, x[ 1], 15, x[ 9], 14);
		a = round3(a, b, c, d, x[ 2], 14, x[11], 12);
		d = round3(d, a, b, c, x[ 7],  8, x[ 8], 13);
		c = round3(c, d, a, b, x[ 0], 13, x[12],  5);
		b = round3(b, c, d, a, x[ 6],  6, x[ 2], 14);
		a = round3(a, b, c, d, x[13],  5, x[10], 13);
		d = round3(d, a, b, c, x[11], 12, x[ 0], 13);
		c = round3(c, d, a, b, x[ 5],  7, x[ 4],  7);
		b = round3(b, c, d, a, x[12],  5, x[13],  5);

		a = round4(a, b, c, d, x[ 1], 11, x[ 8], 15);
		d = round4(d, a, b, c, x[ 9], 12, x[ 6],  5);
		c = round4(c, d, a, b, x[11], 14, x[ 4],  8);
		b = round4(b, c, d, a, x[10], 15, x[ 1], 11);
		a = round4(a, b, c, d, x[ 0], 14, x[ 3], 14);
		d = round4(d, a, b, c, x[ 8], 15, x[11], 14);
		c = round4(c, d, a, b, x[12],  9, x[15],  6);
		b = round4(b, c, d, a, x[ 4],  8, x[ 0], 14);
		a = round4(a, b, c, d, x[13],  9, x[ 5],  6);
		d = round4(d, a, b, c, x[ 3], 14, x[12],  9);
		c = round4(c, d, a, b, x[ 7],  5, x[ 2], 12);
		b = round4(b, c, d, a, x[15],  6, x[13],  9);
		a = round4(a, b, c, d, x[14],  8, x[ 9], 12);
		d = round4(d, a, b, c, x[ 5],  6, x[ 7],  5);
		c = round4(c, d, a, b, x[ 6],  5, x[10], 15);
		b = round4(b, c, d, a, x[ 2], 12, x[14],  8);

		return new int4 {
			previous[1] + c[0] + d[1],
			previous[2] + d[0] + a[1],
			previous[3] + a[0] + b[1],
			previous[0] + b[0] + c[1]
		};
    }


    public () {  }

    public int main(String[] arguments) throws Exception {
        PrintStream out = System.out;
        computeAndPrintlnHash(out, "");
        computeAndPrintlnHash(out, "a");
        computeAndPrintlnHash(out, "abc");
        computeAndPrintlnHash(out, "aaa100");
        computeAndPrintlnHash(out, "aaa101");
        return 0;
    }
}