Какова цель низкого и высокого клев при преобразовании строки в HexString - PullRequest
0 голосов
/ 04 мая 2018

Недавно я изучал несколько примеров MD5, чтобы начать понимать безопасность, и MD5 по большей части довольно прост для понимания и является хорошей отправной точкой, даже если он больше не защищен. Несмотря на это, у меня есть вопрос, касающийся высоких и слабых мест, когда дело доходит до преобразования строки в шестнадцатеричную строку.

Так что я знаю, что верхний и нижний полубайты равны половине байта или также могут быть шестнадцатеричными цифрами, которые представляют одну шестнадцатеричную цифру. Однако я не понимаю, как именно они работают и какова их цель. Я искал в Google, и я не могу найти много ответов, которые помогут объяснить, что они делают в контексте, в котором они находятся. Вот контекст конверсии:

private static String toHexString( byte[] byteArray )
    {
        final String HEX_CHARS = "0123456789ABCDEF"; 

        byte[] result = new byte[byteArray.length << 1];
        int len = byteArray.length;
        for( int i = 0 ; i < len ; i++ )
        {
            byte b = byteArray[i]
            int lo4 = b & 0x0F;
            int hi4 = ( b & 0xF0 ) >> 4;


            result[i * 2] = (byte)HEX_CHARS.charAt( hi4 );
            result[i * 2 + 1] = (byte)HEX_CHARS.charAt( lo4 );
        }
        return new String( result );
    } 

Я не совсем понимаю, что происходит в заявлении for. Я был бы признателен за любую помощь в понимании этого, и если есть какая-то ссылка на некоторые места, где я могу узнать больше об этом, пожалуйста, также оставьте это.

Я понимаю базовое определение клев, но не операции и то, что делает присвоение числу 4.

Если мне нужно опубликовать полный пример кода, я просто спрошу, так как не уверен, если это необходимо.

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Этот код просто преобразует байтовый массив в шестнадцатеричное представление. В цикле for каждый байт преобразуется в два символа. Я думаю, что это легче понять на примере.

Предположим, что один из байтов в вашем массиве, скажем, 218 (без знака). Это 1101 1010 в двоичном виде.

lo4 получает младшие 4 бита, используя байт с битовой маской 00001111:

int lo4 = b & 0x0F;

В результате получается 1010, 10 в десятичном формате.

hi4 получает старшие 4 бита, используя AND с битовой маской 1111 0000 и сдвигая 4 бита вправо:

int hi4 = ( b & 0xF0 ) >> 4;

В результате получается 1101, 13 в десятичном формате.

Теперь, чтобы получить шестнадцатеричное представление этого байта, вам нужно только преобразовать 10 и 13 в их шестнадцатеричные представления и объединить. Для этого вы просто ищите символ в подготовленной строке HEX_CHARS по указанному индексу. 10 -> A, 13 -> D, в результате чего 218 -> DA.

0 голосов
/ 04 мая 2018

Это всего лишь битовые операции. Символ & принимает буквальное значение каждого из них и выполняет логическое и для них.

int lo4 = b & 0x0F;

например, если b = 24, тогда оно будет равно этому

 00011000
+00001111
=00001000

Вторая такая строка делает то же самое для первых четырех битов.

 00011000
+11110000
=00010000

'>>' сдвигает все биты на определенное число в этом направлении, поэтому

00010000 >> 4 = 00000001. 

Это сделано для того, чтобы вы могли получить шестнадцатеричное значение из числа. Поскольку каждый символ в шестнадцатеричном формате может представлять 4 бита, разделив число на части по 4 бита, мы можем преобразовать его.

в случае b = 24 у нас нет lo4 = 1000 или 8 и hi4 = 0001 или 1. Последняя часть цикла назначает символьное значение для каждого.

Hex_chars [hi4] = '1' и Hex_chars [lo4] = '8', что дает вам «18» для той части строки, которая равна 24 в гексах.

...