Здраствуйте. Доработал этого метода используя этот источник "http://en.wikipedia.org/wiki/SHA_hash_functions" и он работает правильно дла всякого слова, исключая пустого сообщения. Ошибка такая, берем код ASCII для каждого символа сообщения которое имеет 8 битовою бинарную представления. В нашем случае сообщение пустое и мы будем добавлять '1' к бинарному представления слова после чего ещё 447 нулей '0' чтобы он стал кратным на 448. Потом 64 битовое представление длины первоначальнного сообщения, т.е. 64 нулей в нашем случае чтобы получить 512 битовой блок. Когда мы обрабатываем наш 512 битовой блок разделяя его на 32 битовые блоки и берем из них int значение для далнеещих обработок, наш первый блок получается равым на "10000000000000000000000000000000" а это выходить за пределами int'а, т.е 2147483648>2147483647. Пробовал делать метод со всеми long'ами но дает совсем другие результаты. Что делать? Новый код Код |
public class SHA_1 { private static int bitsInCharacter = 8; public static void main(String[] args){ System.out.println(hash(""));//put message to hash() method as argument //it will not for "" } static String hash(String text){ String[] bitView = toNormalBinaryString(text); String allStr = ""; for (String s: bitView) allStr += s; //System.out.println("allStr.length() = "+allStr.length()); String paddedStr = correctStr(allStr); String hash = doHash(paddedStr); return hash; } private static String doHash(String readyStr){ //System.out.println("readyStr.length() = "+readyStr.length()); int h0=0x67452301, h1=0xEFCDAB89, h2=0x98BADCFE; int h3=0x10325476, h4=0xC3D2E1F0, a, b, c, d, e; // long h0=0x67452301, h1=0xEFCDAB89, h2=0x98BADCFE; // long h3=0x10325476, h4=0xC3D2E1F0, a, b, c, d, e; int size = readyStr.length()/512; System.out.println("size = "+size); String[] pieces512 = new String[size]; int currIndx=0, left=0, rigth=0; while (currIndx<size){ pieces512[currIndx]=readyStr.substring(left, left+512); left += 512; currIndx++; } currIndx=0; left=0; rigth=0; String arr512=""; int[] w = new int[80]; // long[] w = new long[80]; String[] wHexStr = new String[80]; String piece32 = new String(); int temp=0; // long temp=0; while (currIndx<size){ System.out.println("Working for "+currIndx+" block of 512"); arr512 = pieces512[currIndx]; left=rigth=0; for (int i=0; i<16; i++){ piece32 = arr512.substring(left, left+32); left += 32; System.out.print(piece32+" "); wHexStr[i] = Integer.toHexString(Integer.parseInt(piece32, 2)); w[i] = Integer.parseInt(wHexStr[i], 16); // wHexStr[i] = Long.toHexString(Long.parseLong(piece32, 2)); // w[i] = Long.parseLong(wHexStr[i], 16); System.out.print("wHexStr["+i+"] = "); println(wHexStr[i]); } for (int j=16; j<80; j++){ w[j]=leftRotate(w[j-3]^w[j-8]^w[j-14]^w[j-16], 1); wHexStr[j] = Integer.toHexString(w[j]); // wHexStr[j] = Long.toHexString(w[j]); } /*int myIndex = 0; for (String k: wHexStr){ System.out.print("wHexStr["+myIndex+"]= "); println(k); myIndex++; }*/ a=h0; b=h1; c=h2; d=h3; e=h4; for (int t=0; t<80; t++){ temp = leftRotate(a, 5)+f(b, c, d, t)+e+w[t]+k(t); e=d; d=c; c=leftRotate(b, 30); b=a; a=temp; // System.out.print("\nt = "+t+": "+Long.toHexString(a)+" "); // System.out.print(Long.toHexString(b)+" "); // System.out.print(Long.toHexString(c)+" "); // System.out.print(Long.toHexString(d)+" "); // System.out.print(Long.toHexString(e)+" "); } h0=h0+a; h1=h1+b; h2=h2+c; h3=h3+d; h4=h4+e; currIndx++; } String digest = ""; digest += lastCorrect(Integer.toHexString(h0))+""; digest += lastCorrect(Integer.toHexString(h1))+""; digest += lastCorrect(Integer.toHexString(h2))+""; digest += lastCorrect(Integer.toHexString(h3))+""; digest += lastCorrect(Integer.toHexString(h4))+""; /*digest += lastCorrect(Long.toHexString(h0))+""; digest += lastCorrect(Long.toHexString(h1))+""; digest += lastCorrect(Long.toHexString(h2))+""; digest += lastCorrect(Long.toHexString(h3))+""; digest += lastCorrect(Long.toHexString(h4))+"";*/ return digest; } private static String lastCorrect(String must8){ while (must8.length()<8) must8 = "0"+must8; return must8; } private static int leftRotate(int number, int pos){ return (number<<pos) | (number>>>(32-pos)); } private static int k(int t){ int temp = 0; if ((t>=0)&&(t<=19)) temp=0x5A827999; if ((t>=20)&&(t<=39)) temp=0x6ED9EBA1; if ((t>=40)&&(t<=59)) temp=0x8F1BBCDC; if ((t>=60)&&(t<=79)) temp=0xCA62C1D6; return temp; } private static int f(int b, int c, int d, int t){ int result=0; if ((t>=0)&&(t<=19)) result=((b&c)|((~b)&d)); if ((t>=20)&&(t<=39)) result=(b^c^d); if ((t>=40)&&(t<=59)) result=((b&c)|(b&d)|(c&d)); if ((t>=60)&&(t<=79)) result=(b^c^d); return result; } private static String correctStr(String str){ int preLength = str.length(); StringBuffer stBuf = new StringBuffer(str); stBuf.append('1'); int afterLength = stBuf.length(); int toCongurent512 = afterLength%512; int countZeros = (448-toCongurent512>0)?(448-toCongurent512): (448+512-toCongurent512); int index = 0; while (index<countZeros){ stBuf.append('0'); index++; } StringBuffer myBin = new StringBuffer( Integer.toBinaryString(preLength)); if (myBin.length()<64){ myBin.reverse(); while (myBin.length()<64){ myBin.append('0'); } myBin.reverse(); } stBuf.append(myBin); return stBuf.toString(); } private static void println(String str){ int lngth = str.length(), index=0; while (index<8-lngth){ System.out.print('0'); index++; } System.out.print(str+"\n"); } private static void println(int nt){ println(String.valueOf(nt)); } private static String[] toNormalBinaryString(String txt){ int length = txt.length(); byte[] bt = new byte[length]; String[] result = new String[length]; try{ bt = txt.getBytes("ASCII"); } catch (Exception e){ System.out.println("Some Error in get ASCII code"); } StringBuffer stB; int delta=0; for (int i=0; i<bt.length; i++){ stB = new StringBuffer(Integer.toString(bt[i], 2)); stB.reverse(); delta = bitsInCharacter-stB.length(); if (delta != 0){ for (int j=0; j<delta; j++) stB.append('0'); } stB.reverse(); result[i] = stB.toString(); } /*for (int i=0; i<length; i++){ System.out.println("bt["+i+"] = "+bt[i]); System.out.println("result["+i+"] = "+result[i]); }*/ return result; } }
|
Вот здесь пример зделанное кемто на JavaScript работает для всякого сообщение
|