Вы находитесь на странице: 1из 3

SHA1 ALGORITHM

SHA is a cryptographic message digest algorithm similar to MD5. SHA-1


hash considered to be one of the most secure hashing functions,
producing a 160-bit digest (40 hex numbers) from any data with a
maximum size of 264 bits. While Java has built in classes to compute SHA
1 hash, it's quite uneasy to use them for a simple task -- calculate SHA-1
hash and return 40-byte hexadecimal string.
PROGRAM
/*
* To change this license header, choose License Headers in Project
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package sha1_hash;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
/**
*
* @author BIBIN RAJ B S
*/
public class SHA1_HASH {
/**
* @param args the command line arguments
* @throws java.security.NoSuchAlgorithmException
*/
public static void main(String[] args) throws NoSuchAlgorithmException
{
// TODO code application logic here
Scanner sc=new Scanner(System.in);
System.out.print("Enter the string to hash:");
String input=sc.next();
System.out.println("The SHA1 hash of the input string:"+
(compSHA1(input)));
}
public static StringBuffer compSHA1(String in) throws
NoSuchAlgorithmException
{
byte [] input=in.getBytes();
//Get a message digest object using SHA1 algorithm
MessageDigest objSHA1=MessageDigest.getInstance("SHA1");

//Compute digest and print out


objSHA1.update(input);
byte [] digest=objSHA1.digest();
//Convert byte digest to hex format
StringBuffer hexDigest=new StringBuffer();
for(int i=0;i<digest.length;i++)
{
hexDigest.append(Integer.toString((digest[i] & 0xff)+ 0x100,
16).substring(1));
}
return hexDigest;
}
}
EXPLANATION
Presumably most of the code is clear and the only mystery for you here is this
expression:
(bytes[i] & 0xff) + 0x100
The first part: bytes[i] & 0xff

widens the byte at position i to an int value with zeros in bit positions 831. In Java, the byte data type is a signed integer value, so the widening
sign-extends the value. Without the & 0xff, values greater than 0x7f would
end up as negative int values. The rest is then fairly obvious: it adds
0x100, which simply turns on the bit at index 8 (since it is guaranteed to
be 0 in(bytes[i] & 0xff). It is then converted to a hexStringvalue by the call
toInteger.toString(..., 16)`.
The reason for first adding 0x100 and then stripping off the 1 (done by the
substring(1) call, which takes the substring starting at position 1 through
the end) is to guarantee two hex digits in the end result. Otherwise, byte
values below 0x10 would end up as one-character strings when converted
to hex.
It's debatable whether all that has better performance (it certainly isn't
clearer) than:
sb.append(String.format("%02x", bytes[i]));
(OR)
It's a really messy way of translating to a hexadecimal string.

1) & 0xFF performs a binary AND, causing the returning value to be


between 0 and 255 (which a byte always is anyway)
2) + 0x100 adds 256 to the result to ensure the result is always 3
digits
3) Integer.toString(src, 16) converts the integer to a string with helix
16 (hexadecimal)
4) Finally .substring(1) strips the first character (the 1 from step 2)
So, this is a very elaborate and obfuscated way to convert a byte to an
always 2-character hexadecimal string.

(OR)
Bytes are signed: they could be negative. When a negative byte is
handled by Integer.toString() generates a string beginning with "FFFFFF",
but this doesn't happen with positive bytes, so the length of the resulting
string is not fixed. The & 0xff converts the byte to an unsigned integer.
Then 0x100 is added to ensure that the hex string is 3 chars long; this is
needed because we want a string with 2 hex digits for each byte but a
byte between 0 and 15 would produce 1 char only. Finally the third digit is
discarded with substring(1).

Вам также может понравиться