// Arup Guha
// 10/8/2020
// DES S-box Tester to help CIS 3362 students

import java.util.*;
import java.io.*;

public class SBoxTester {

	public static byte[][][] sboxes;

	public static void main(String[] args) throws Exception {
	
		// Read in the boxes from the file.
		Scanner fin = new Scanner(new File("sboxes.txt"));
		sboxes = new byte[8][4][16];
		for (int i=0; i<8; i++)
			for (int j=0; j<64; j++)
				sboxes[i][j/16][j%16] = (byte)(fin.nextInt());
		fin.close();
		
		// Read in sbox input.
		Scanner stdin = new Scanner(System.in);
		System.out.println("Please enter the sbox input as 12 hex characters, in a single string.");
		String tmp = stdin.next().toLowerCase();
		byte[] in = new byte[6];
		for (int i=0; i<6; i++)
			in[i] = convertToByte(tmp.substring(2*i, 2*i+2));
		
		// Do each s-box.
		for (int i=0; i<8; i++) {
		
			// Bit locations.
			int rbit1 = 6*i;
			int rbit2 = 6*i+5;
			
			// Get row and column.
			int row = (getBit(rbit1, in) << 1) + getBit(rbit2, in);
			int col = getFourBits(rbit1+1, in);
			
			// Get result and output.
			byte res = sboxes[i][row][col];
			System.out.println("Entry in s-box "+(i+1)+" in row "+row+" and col "+col+" is "+res);
		}
	}
	
	// Returns the bit in location loc in the byte array arr.
	public static int getBit(int loc, byte[] arr) {
		int idx = loc/8;
		int bitIdx = 7 - loc%8;
		return (arr[idx] & (1<<bitIdx)) != 0 ? 1 : 0;
	}
	
	// Returns the 0-15 value of the four bits starting at bit location loc in arr.
	public static int getFourBits(int loc, byte[] arr) {
		return ((getBit(loc,arr)<<3) + (getBit(loc+1,arr)<<2) + (getBit(loc+2,arr)<<1) + getBit(loc+3,arr));
	}
	
	// s must be two hex chars, returns unsigned byte value.
	public static byte convertToByte(String s) {
		s = s.toLowerCase();
		return (byte)((val(s.charAt(0))<<4)+val(s.charAt(1)));
	}
	
	// Returns the byte value (0 to 15) of the hex character c.
	public static byte val(char c) {
		if (c >= '0' && c <= '9') return (byte)(c-'0');
		return (byte)(c-'a'+10);
	}	
}