0

I have tried to implement a program to hash an integer array using SHA-512. I found some solution1 solution2 to convert the byte[] which contains decimal values to hexadecimals. When I compared the string output to decimal values I found out that for negative values there are some differences. I don't know what is the problem. I tried to convert values to each other and also looked at unsigned, etc but I can not found out what is wrong. FYI, I want to use bytes in an xor function and don't need strings but I'm scared that some thing might be wrong in my code.

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author martin
 */
public class NewMain {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Integer[][] integerBlock = new Integer[5][5];
        //put some values in the matrix integerBlock
        int i,j;
        for(i=0; i<integerBlock.length; i++){
            for(j=0; j<integerBlock.length; j++){
                integerBlock[i][j] = i+j;
            }
        }
        //convert integerBlock to a string
        String str = IntToStr(integerBlock);
        System.out.println("original string is :      " + str);

        //hash the string using SHA512
        byte[] shaByteResult = SHA512(str);

        //print the generated key in hex
        System.out.println("byteArray2Hex  method:    " + byteArray2Hex(shaByteResult));
        System.out.println("byteArray2Hex2 method:    " + byteArray2Hex2(shaByteResult));

        //print the generated key in decimal
        System.out.print("Decimal values in bytes[]:");
        for(i=0; i< shaByteResult.length ;i++)
                System.out.print(shaByteResult[i]);      

        System.out.println("Compare decimal and correspondig hex");
        for(i=0; i< shaByteResult.length ;i++)
                System.out.println("bytes[" +i +"] = " + " decimal is " + shaByteResult[i] + "  hexadecimal " + Integer.toString((shaByteResult[i] & 0xff) + 0x100, 16).substring(1));
}

    public static String IntToStr(Integer[][] integerBlock){
        StringBuilder SB = new StringBuilder();

        int i,j;
        for(i=0; i<integerBlock.length; i++){
            for(j=0; j<integerBlock.length; j++){
                SB.append(integerBlock[i][j].toString());
                //stringBlock = stringBlock.concat(integerBlock[i][j].toString());                
            }
        }
        return SB.toString();
    }

    private static String byteArray2Hex(final byte[] bytes) {

        Formatter formatter = new Formatter();

        for (byte b : bytes) {
            formatter.format("%02x", b);
        }
        return formatter.toString();
    }
    //another solution
    private static String byteArray2Hex2(final byte[] bytes) {

        StringBuilder sb = new StringBuilder();
        int i;

        for(i=0; i< bytes.length ;i++)
            sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));

        return sb.toString();
    }

    public static byte[] SHA512(String str){
        byte[] bytes = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-512");
            md.update(str.getBytes());
            bytes = md.digest();

        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(NewMain.class.getName()).log(Level.SEVERE, null, ex);
        }
         return bytes;
    }    
}

The out put is:

original string is :      0123412345234563456745678
byteArray2Hex  method:    0fe5246a2a26080194c19e86ee1e6a40ceb298194190eacace0d3b1499186220b5cd92a1bdd25f8b4023566c211cc462974c3884a128336b76a1e990fe6f3c54
byteArray2Hex2 method:    0fe5246a2a26080194c19e86ee1e6a40ceb298194190eacace0d3b1499186220b5cd92a1bdd25f8b4023566c211cc462974c3884a128336b76a1e990fe6f3c54
Decimal values in bytes[]:15-2736106423881-108-63-98-122-183010664-50-78-1042565-112-22-54-50135920-103249832-75-51-110-95-67-4695-1176435861083328-6098-1057656-124-954051107118-95-23-112-21116084Compare decimal and correspondig hex
bytes[0] =  decimal is 15  hexadecimal 0f
bytes[1] =  decimal is -27  hexadecimal e5
bytes[2] =  decimal is 36  hexadecimal 24
bytes[3] =  decimal is 106  hexadecimal 6a
bytes[4] =  decimal is 42  hexadecimal 2a
bytes[5] =  decimal is 38  hexadecimal 26
bytes[6] =  decimal is 8  hexadecimal 08
bytes[7] =  decimal is 1  hexadecimal 01
bytes[8] =  decimal is -108  hexadecimal 94
bytes[9] =  decimal is -63  hexadecimal c1
bytes[10] =  decimal is -98  hexadecimal 9e
bytes[11] =  decimal is -122  hexadecimal 86
bytes[12] =  decimal is -18  hexadecimal ee
bytes[13] =  decimal is 30  hexadecimal 1e
bytes[14] =  decimal is 106  hexadecimal 6a
bytes[15] =  decimal is 64  hexadecimal 40
bytes[16] =  decimal is -50  hexadecimal ce
bytes[17] =  decimal is -78  hexadecimal b2
bytes[18] =  decimal is -104  hexadecimal 98
bytes[19] =  decimal is 25  hexadecimal 19
bytes[20] =  decimal is 65  hexadecimal 41
bytes[21] =  decimal is -112  hexadecimal 90
bytes[22] =  decimal is -22  hexadecimal ea
bytes[23] =  decimal is -54  hexadecimal ca
bytes[24] =  decimal is -50  hexadecimal ce
bytes[25] =  decimal is 13  hexadecimal 0d
bytes[26] =  decimal is 59  hexadecimal 3b
bytes[27] =  decimal is 20  hexadecimal 14
bytes[28] =  decimal is -103  hexadecimal 99
bytes[29] =  decimal is 24  hexadecimal 18
bytes[30] =  decimal is 98  hexadecimal 62
bytes[31] =  decimal is 32  hexadecimal 20
bytes[32] =  decimal is -75  hexadecimal b5
bytes[33] =  decimal is -51  hexadecimal cd
bytes[34] =  decimal is -110  hexadecimal 92
bytes[35] =  decimal is -95  hexadecimal a1
bytes[36] =  decimal is -67  hexadecimal bd
bytes[37] =  decimal is -46  hexadecimal d2
bytes[38] =  decimal is 95  hexadecimal 5f
bytes[39] =  decimal is -117  hexadecimal 8b
bytes[40] =  decimal is 64  hexadecimal 40
bytes[41] =  decimal is 35  hexadecimal 23
bytes[42] =  decimal is 86  hexadecimal 56
bytes[43] =  decimal is 108  hexadecimal 6c
bytes[44] =  decimal is 33  hexadecimal 21
bytes[45] =  decimal is 28  hexadecimal 1c
bytes[46] =  decimal is -60  hexadecimal c4
bytes[47] =  decimal is 98  hexadecimal 62
bytes[48] =  decimal is -105  hexadecimal 97
bytes[49] =  decimal is 76  hexadecimal 4c
bytes[50] =  decimal is 56  hexadecimal 38
bytes[51] =  decimal is -124  hexadecimal 84
bytes[52] =  decimal is -95  hexadecimal a1
bytes[53] =  decimal is 40  hexadecimal 28
bytes[54] =  decimal is 51  hexadecimal 33
bytes[55] =  decimal is 107  hexadecimal 6b
bytes[56] =  decimal is 118  hexadecimal 76
bytes[57] =  decimal is -95  hexadecimal a1
bytes[58] =  decimal is -23  hexadecimal e9
bytes[59] =  decimal is -112  hexadecimal 90
bytes[60] =  decimal is -2  hexadecimal fe
bytes[61] =  decimal is 111  hexadecimal 6f
bytes[62] =  decimal is 60  hexadecimal 3c
bytes[63] =  decimal is 84  hexadecimal 54
Amiri
  • 2,417
  • 1
  • 15
  • 42

1 Answers1

0

A constant holding the maximum value a byte can have, 2^7-1

It means each byte has value between -127 and 127 the most significant bit is used as the sign flag. Thus,

bytes[0] =  decimal is 15  hexadecimal 0f and binary is  0000 1111
bytes[1] =  decimal is -27  hexadecimal e5 and binary is 1110 0101 is 229 unsigned
bytes[2] =  decimal is 36  hexadecimal 24 and binary is  0010 0100
bytes[3] =  decimal is 106  hexadecimal 6a and binary is 0110 1010
bytes[4] =  decimal is 42  hexadecimal 2a and binary is  0010 1010
bytes[5] =  decimal is 38  hexadecimal 26 and binary is  0010 0110
bytes[6] =  decimal is 8  hexadecimal 08 and binary is   0000 1000 
bytes[7] =  decimal is 1  hexadecimal 01 and binary is   0000 0001

Then, Java byte is signed and is interpreted as two compliments that means all bits are reversed and added by one. Thus, for e5 or 229 or 1110 0101

1110 0101 --twoCom- > 0001 1010 --(+1)--> 0001 1011 (27) apply sign bit --- > -27

Amiri
  • 2,417
  • 1
  • 15
  • 42