Can someone explain the conversion from a byte array to a sixth string?

I recently started learning MD5 hashing (in Java), and while I found algorithms and methods to help me with this, I was left wondering how this works.

First, I found the following from this URL :

private static String convertToHex(byte[] data) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < data.length; i++) { int halfbyte = (data[i] >>> 4) & 0x0F; int two_halfs = 0; do { if ((0 <= halfbyte) && (halfbyte <= 9)) buf.append((char) ('0' + halfbyte)); else buf.append((char) ('a' + (halfbyte - 10))); halfbyte = data[i] & 0x0F; } while(two_halfs++ < 1); } return buf.toString(); } 

I did not find the need to use bit-shift in Java, so I'm a little rusty. Is someone enough to illustrate (in simple words) how exactly this code performs the conversion? "→>"?

I also found other solutions in StackOverflow, such as here and here , which uses BigInteger instead:

 try { String s = "TEST STRING"; MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(s.getBytes(),0,s.length()); String signature = new BigInteger(1,md5.digest()).toString(16); System.out.println("Signature: "+signature); } catch (final NoSuchAlgorithmException e) { e.printStackTrace(); } 

Why does this work too, and which method is more efficient?

Thank you for your time.

+4
source share
4 answers
 private static String convertToHex(byte[] data) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < data.length; i++) { 

Up to this point ... only basic setup and starting a loop to go through all the bytes in the array

  int halfbyte = (data[i] >>> 4) & 0x0F; 

Bytes when converting to hexadecimal are two hexadecimal digits or 8 binary digits, depending on which base you are looking at. The above operator shifts the high 4 bits down (→> - unsigned right shift) and the logical ANDs from 0000 1111, so the result will be an integer equal to the high 4 bits of the byte (the first hexadecimal digit).

Let's say 23 was input, it is 0001 0111 in binary format. The shift makes and logical AND hides it to 0000 0001.

  int two_halfs = 0; do { 

It just sets the do / while loop to execute twice

  if ((0 <= halfbyte) && (halfbyte <= 9)) buf.append((char) ('0' + halfbyte)); else buf.append((char) ('a' + (halfbyte - 10))); 

Here we show the actual sixth digit, basically just using a zero or a character as a starting point and moving on to the correct character. The first if statement covers all the digits 0-9, and the second covers all the digits 10-15 (af in hexadecimal format)

Again, using our example, 0000 0001 in decimal value is 1. We get to the top if block and add 1 to the character '0' to get the character '1', add it to the string and go to.

  halfbyte = data[i] & 0x0F; 

Now we will configure an integer to simply combine the low-order bits with the byte and repeat.

Again, if our input was 23 ... 0001 0111 after the logical AND it becomes only 0000 0111, which is 7 decimal. Repeat the same logic as above and the “7” symbol will be displayed.

  } while(two_halfs++ < 1); 

Now we just go to the next byte in the array and repeat.

  } return buf.toString(); } 

To answer your next question, the Java API already has a basic conversion utility built into BigInteger. See the documentation for toString (int radix) .

Without knowing the implementation used by the Java API, I cannot say for sure, but I would bet that implementing Java is more efficient than the first somewhat simple algorithm that you published.

+10
source

To answer this bit:

Why does this work too?

This is not true. At least not in the way the loop version does. new BigInteger (...). toString (16) will not show leading zeros to be used in the previous version. Usually for something like writing a byte array (especially one representing something like a hash) you need fixed-length output, so if you want to use this version, you have to lay it out accordingly.

+2
source

For a detailed explanation of bitrate, check the answers in the next SO question. What are bit shift operators (bit-shift) and how do they work?

It seems he is trying to convert one byte to a number less than 16, thereby he can easily determine which caracther is a byte with code

  if ((0 <= halfbyte) && (halfbyte <= 9)) buf.append((char) ('0' + halfbyte)); else buf.append((char) ('a' + (halfbyte - 10))); 

This is a simplified answer, but im not so bright: D

+1
source

You do not need to write these things yourself, because they are already written in apache-commons-codec:

 import org.apache.commons.codec.binary.Hex; ... Hex.encodeHexString(byte[] array) 

There are many useful methods in the Hex class.

0
source

Source: https://habr.com/ru/post/1286741/


All Articles