Skip to content

Instantly share code, notes, and snippets.

@JAromando
Created January 10, 2017 17:34
Show Gist options
  • Select an option

  • Save JAromando/8221be0a7df6b0bdc957a19ecb044f59 to your computer and use it in GitHub Desktop.

Select an option

Save JAromando/8221be0a7df6b0bdc957a19ecb044f59 to your computer and use it in GitHub Desktop.
package com.company; //used for IntelliJ Idea
/*SHA1 Hash Implementation
//Authors: John Aromando/Matt Fishman
//
//Takes in plain text and returns the HexString value of the 160 number result.
//The project will return the plain text, the Decimal, Binary, and Hex values of the plain text and the result of the program.
//Spaces are acceptable when providing the plain text.
//
*/
import java.util.Scanner;
public class sha1 {
public static int messLength = 0;
public static void main(String[] args) {
//Getting the word
System.out.println("Insert a word a phrase to be hashed");
Scanner sc = new Scanner(System.in);
String word = sc.nextLine();
System.out.println("Plain Text: " + word);
//Converting the word to binary
String binary = convertToBinary(word);
messLength = binary.length();
calculateMod(word, binary);
}
public static String convertToBinary(String word) {
byte[] bytes = word.getBytes();
StringBuilder binary = new StringBuilder();
for (byte b : bytes) {
int val = b;
for (int i = 0; i < 8; i++) {
binary.append((val & 128) == 0 ? 0 : 1);
val <<= 1;
}
binary.append(' ');
}
return binary.toString();
}
public static void calculateMod(String word, String binary) {
int binaryMessageLength = word.length() * 8 - 8; //the -8 will be taken into account below.
String endBitLength = calculateMessageLength(binaryMessageLength+8); //add back 8 for accuracy
int subMod = endBitLength.length();
int temp = (binaryMessageLength) % 512;
if (432 - temp < 0) {
int x = 512 - temp;
temp = x + 440 + temp + 64;
} else {
temp = 432 - temp;
}
int binaryZeros = temp;
String onePadded = "10000000"; //add back the removed 8
binary = binary.replaceAll("\\s+", ""); //remove spaces
createMessageLength(binary, onePadded, binaryZeros, endBitLength); //creates the 512 bit message
}
public static String calculateMessageLength(int bitLength) {
String tempBitsLength = Integer.toBinaryString(bitLength);
StringBuilder sb = new StringBuilder(tempBitsLength);
int temp = 64 - tempBitsLength.length();
while (temp > 0) {
sb.insert(0, 0);
temp--;
}
return sb.toString();
}
//create complete message
public static String createMessageLength(String message, String paddedOne, int zeros, String endLength) {
StringBuilder messageBinary = new StringBuilder(message);
messageBinary.insert(messageBinary.toString().length(), paddedOne);
while (zeros > 0) {
messageBinary.insert(messageBinary.toString().length(), 0);
zeros--;
}
messageBinary.insert(messageBinary.toString().length(), endLength);
String m = printMessage(messageBinary.toString());
m = m.replaceAll("\\s+", "");
int[] mArray = new int[m.toString().length()/32];
for (int i = 0; i < m.toString().length(); i+=32) {
mArray[i/32] = Integer.valueOf(m.substring(i+1, i+32),2);
if(m.charAt(i) == '1'){
mArray[i/32] |= 0X80000000;
}
System.out.printf("Decimal(iterator), String(Binary), Hex values of input: %d %s %x\n", i, m.substring(i, i+32),mArray[i/32]);
}
hash(mArray);
return messageBinary.toString();
}
public static String printMessage(String message) {
StringBuilder sb = new StringBuilder(message);
int num = message.length();
while (num > 0) {
if (num % 32 == 0) {
sb.insert(num, " ");
}
num--;
}
return sb.toString();
}
private static int leftrotate(int x, int shift) { //leftrotate function
return ((x << shift) | (x >>> (32 - shift))); //>>> is an UNSIGNED shift compared >> which is not
}
//instance variables
private static int h1 = 0x67452301;
private static int h2 = 0xEFCDAB89;
private static int h3 = 0x98BADCFE;
private static int h4 = 0x10325476;
private static int h5 = 0xC3D2E1F0;
private static int k1 = 0x5A827999;
private static int k2 = 0x6ED9EBA1;
private static int k3 = 0x8F1BBCDC;
private static int k4 = 0xCA62C1D6;
private static String hash(int[] z) {
//Extend the sixteen 32-bit words into eighty 32-bit words
int integer_count = z.length;
int[] intArray = new int[80];
int j = 0;
for(int i = 0; i < integer_count; i += 16) {
for(j = 0; j <= 15; j++)
intArray[j] = z[j+i];
for ( j = 16; j <= 79; j++ ) {
//w[i] = (w[i-3] xor w[i-8] xor w[i-14] xor w[i-16]) leftrotate 1
intArray[j] = leftrotate(intArray[j - 3] ^ intArray[j - 8] ^ intArray[j - 14] ^ intArray[j - 16], 1);
//System.out.printf("J: %d ARRAY: %x\n", j, intArray[j]);
}
// calculate A,B,C,D,E:
int A = h1;
int B = h2;
int C = h3;
int D = h4;
int E = h5;
int t = 0; //temp
for ( int x = 0; x <= 19; x++ ) {
//temp = leftrotate(a leftrotate 5) + f(t) + e + w[i] + k
t = leftrotate(A,5)+((B&C)|((~B)&D))+E+intArray[x]+k1;
E=D; D=C; C=leftrotate(B,30); B=A; A=t;
}
for ( int b = 20; b <= 39; b++ ) {
t = leftrotate(A,5)+(B^C^D)+E+intArray[b]+k2;
E=D; D=C; C=leftrotate(B,30); B=A; A=t;
}
for (int c = 40; c <= 59; c++ ) {
t = leftrotate(A,5)+((B&C)|(B&D)|(C&D))+E+intArray[c]+k3;
E=D; D=C; C=leftrotate(B,30); B=A; A=t;
}
for ( int d = 60; d <= 79; d++ ) {
t = leftrotate(A,5)+(B^C^D)+E+intArray[d]+k4;
E=D; D=C; C=leftrotate(B,30); B=A; A=t;
}
h1+=A; h2+=B; h3+=C; h4+=D; h5+=E;
}
String h1Length = Integer.toHexString(h1);
String h2Length = Integer.toHexString(h2);
String h3Length = Integer.toHexString(h3);
String h4Length = Integer.toHexString(h4);
String h5Length = Integer.toHexString(h5);
//System.out.println(h1Length.length());
//Integer.toHexString does not include extra leading 0's
if(h1Length.length() < 8) {
StringBuilder h1L = new StringBuilder(h1Length);
h1L.insert(0,0);
h1Length = h1L.toString();
} else if(h2Length.length() < 8) {
StringBuilder h2L = new StringBuilder(h2Length);
h2L.insert(0,0);
h2Length = h2L.toString();
} else if(h3Length.length() < 8) {
StringBuilder h3L = new StringBuilder(h3Length);
h3L.insert(0,0);
h3Length = h3L.toString();
} else if(h4Length.length() < 8) {
StringBuilder h4L = new StringBuilder(h4Length);
h4L.insert(0,0);
h4Length = h4L.toString();
} else if(h5Length.length() < 8) {
StringBuilder h5L = new StringBuilder(h5Length);
h5L.insert(0,0);
h5Length = h5L.toString();
}
//result
String hh = h1Length + h2Length + h3Length + h4Length + h5Length;
System.out.println("Result: " + hh);
return null;
}
}
@Daniilart01

Daniilart01 commented Jun 3, 2022 •

Copy link
Copy Markdown

Hey, i`ve been learning your code and trying to run it in my JVM, with some data it works ok? but sometimes it gives incorrect hash
For example with line: abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
As i see, I guess the problem is in count of words, that you adding in middle of resultating string attempt to get length that %512 == 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment