Почему SHA-1 хэш длиной 40 символов, если он всего 160 бит?

Название вопроса говорит само за себя. Я исследовал SHA-1, и в большинстве мест я вижу его длиной 40 шестнадцатеричных символов, который для меня составляет 640 бит. Разве это не может быть представлено так же хорошо только с 10 шестнадцатеричными символами 160 бит = 20 байт. И один шестнадцатеричный символ может представлять 2 байта, верно? Почему это вдвое дольше, чем нужно? Чего мне не хватает в моем понимании.

И не может ли SHA-1 быть всего 5 или менее символов, если используется Base32 или Base36?

6 ответов

Решение

Один шестнадцатеричный символ может представлять только 16 различных значений, то есть 4 бита. (16 =24)

40 × 4 = 160.


И нет, вам нужно гораздо больше, чем 5 символов в base-36.

Всего имеется 2160 различных хэшей SHA-1.

2160 = 1640, так что это еще одна причина, почему нам нужно 40 шестнадцатеричных цифр.

Но 2160 = 36160 log362 = 3630,9482..., поэтому вам все равно нужно 31 символ, используя base-36.

Я думаю, что путаница OP происходит из-за того, что строка, представляющая хэш SHA1, занимает 40 байтов (по крайней мере, если вы используете ASCII), что равно 320 битам (не 640 битам).

Причина в том, что хэш находится в двоичном формате, а шестнадцатеричная строка является только его кодировкой. Поэтому, если бы вы использовали более эффективную кодировку (или вообще не использовали кодировку), вы могли бы занять всего 160 бит (20 байт), но проблема в том, что она не будет бинарно-безопасной.

Вы можете использовать base64, но в этом случае вам понадобится около 27-28 байт (или символов) вместо 40 (см. Эту страницу).

На 8-битный байт приходится два шестнадцатеричных символа, а не два байта на шестнадцатеричный символ.

Если вы работаете с 8-битными байтами (как в определении SHA-1), то шестнадцатеричный символ кодирует один высокий или низкий 4-битный полубайт в байте. Таким образом, для полного байта требуется два таких символа.

Мой ответ отличается от предыдущих в моей теории только ТОЧНЫМ происхождением путаницы ОП, а также детскими шагами, которые я приведу для пояснения.

Символ занимает различное количество байтов в зависимости от используемой кодировки ( см. Здесь). В наши дни существует несколько контекстов, когда мы используем 2 байта на символ, например, при программировании на Java ( вот почему). Таким образом, 40 символов Java будут равны 80 байтам = 640 битам, вычисление OP, и 10 символов Java действительно будут инкапсулировать нужное количество информации для хэша SHA-1.

Однако, в отличие от тысяч возможных символов Java, существует только 16 различных шестнадцатеричных символов, а именно 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E и F. Но это не то же самое, что символы Java, и занимают гораздо меньше места, чем кодировки символов Java от 0 до 9 и от A до F. Это символы, обозначающие все возможные значения, представленные всего 4 битами:

0  0000    4  0100    8  1000    C  1100
1  0001    5  0101    9  1001    D  1101
2  0010    6  0110    A  1010    E  1110
3  0011    7  0111    B  1011    F  1111

Таким образом, каждый шестнадцатеричный символ составляет только половину байта, а 40 шестнадцатеричных символов дают нам 20 байтов = 160 битов - длину хеша SHA-1.

2 шестнадцатеричных символа составляют диапазон от 0 до 255, то есть 0x00 == 0 и 0xFF == 255. Таким образом, 2 шестнадцатеричных символа являются 8-битными, что составляет 160 бит для вашего дайджеста SHA.

SHA-1 составляет 160 бит

Это переводит в 20 байтов = 40 шестнадцатеричных символов (2 шестнадцатеричных символа на байт)

Другие вопросы по тегам