// Arup Guha
// Code for CIS 3362 Homework #6
// Please use this hash function for the assignment.

import java.util.*;

public class hash {

	// Allows the user to enter a string and outputs its hash value.
    public static void main(String[] args) {
		Scanner stdin = new Scanner(System.in);
		System.out.println("Please enter a string.");
		char[] inp = stdin.next().toCharArray();
		System.out.println(hashFunction(inp));
    }
   
   	// This is the hash function you must use for homework #6.
    public static long hashFunction(char[] input) {

        int i = 0, n = input.length;
        long buffer = 0x3f290785c16eL;
        while (i < n) {
            long temp = 0L;
            int j;
            for (j=0; j<6 && i+j<n; j++)
            	if (j%2 == 0)
                	temp |= ( ( (long)(f((int)input[i+j])) ) << (8*j)  );
                else
                	temp |=( ( (long)input[i+j])  << (8*j)  );
            i += 6;

            buffer = f2(buffer ^ temp);
        }
        return buffer;
    }

    // value must be 8 bits. Swaps the left and the right halves and runs
    // each through an s-box.
    public static long f(long value) {
        value = reverse(value);
        long left = (value & (0xf0)) >> 4;
        long right = value & (0xf);
        return (long)((box((int)left) << 4) | box((int)right));
    }

    // value must be 8 bits. It's reverse (in binary) is returned.
    public static long reverse(long value) {
        int i;
        long ans = 0L;
        for (i=0; i<8; i++) {
            ans = (ans << 1L) | (value & 1L);
            value = value >> 1;
        }
        return ans;
    }

    // Random s-box of values. 
    public static int box(int value) {
        int ans[] = {3, 9, 2, 0, 12, 14, 15, 1, 11, 5, 7, 8, 4, 10, 13, 6};
        return ans[value];
    }

    // A second random s-box of values.
    public static int box2(int value) {
        return (53*value)%64;
    }

    // A second function based on the sbox. Value is once again reversed, with
    // another substitution into a different sbox.
    public static long f2(long value) {

        int i;
        long ans = 0L;
        for (i=0; i<8; i++) {
            long index = value & 0x3fL;
            ans = (ans << 6) | box2((int)index);
            value = value >> 6;
        }
        return ans;
    }

}
