Почему функции хеширования, такие как sha1, используют только до 16 различных символов (шестнадцатеричный)? - PullRequest
5 голосов
/ 03 июня 2011

Извините за это любопытство, которое у меня есть.

sha1 использует [a-f0-9] символов для своей функции хеширования.Могу ли я знать, почему он не использует все возможные символы [a-z0-9], используя все доступные символы, это может привести к увеличению числа возможных различных хэшей, что снижает вероятность вероятного столкновения.не думаю, что это реальный вопрос, просто оставьте комментарий, я немедленно удалю этот вопрос.,Правильный факт: sha1 - 160 бит двоичных данных (цит.).Я добавил это, чтобы избежать путаницы.

Ответы [ 5 ]

12 голосов
/ 03 июня 2011

Вы путаете представление с контентом .

sha1 - это 160 бит двоичных данных. Вы можете также легко представить это с помощью:

hex: 0xf1d2d2f924e986ac86fdf7b36c94bcdf32beec15
decimal: 1380568310619656533693587816107765069100751973397
binary: 1111000111010010110100101111100100100100111010011000011010101100100001101111110111110111101100110110110010010100101111001101111100110010101111101110110000010101
base 62: xufK3qj2bZgDrLA0XN0cLv1jZXc

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

Вывод base 62 генерируется с помощью этого маленького кусочка рубина:

#!/usr/bin/ruby

def chars_from_hex(s)
  c = s % 62
  s = s / 62
  if ( s > 0 )
    chars_from_hex(s)
  end
  if (c < 10)
      print c
  elsif (c < 36)
      print "abcdefghijklmnopqrstuvwxyz"[c-11].chr()
  elsif (c < 62)
      print "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[c-37].chr()
  else
      puts "error c", c
  end
end

chars_from_hex(0xf1d2d2f924e986ac86fdf7b36c94bcdf32beec15)

Он использует стандартную идиому для преобразования с одной базы на другую и рассматривает 0-9 как 0-9, a-z как 10-35, A-Z как 36-61. Он может быть тривиально расширен для поддержки большего количества цифр, например, включая !@#$%^&*()-_=+\|[]{},.<>/?;:'"~` если хотите. (Или любой из огромного массива кодов Unicode .)

@ yes123 задал вопрос о представлении ascii хеша специально, поэтому вот результат интерпретации 160-битного хеша непосредственно как ascii:

ñÒÒù$é¬ý÷³l¼ß2¾ì

Это выглядит не очень, потому что:

  • ascii не имеет хорошего печатаемого представления для байтовых значений менее 32
  • сама ascii не может представлять байтовые значения больше 127, от 127 до 255 интерпретируется в соответствии с iso-8859-01 или другими схемами кодирования символов

Это базовое преобразование также может быть практически полезным; метод кодирования Base64 использует 64 (вместо моих 62) символа для представления 6 битов одновременно; ему нужны еще два символа для «цифр» и символ для заполнения. UUEncoding выбрал другой набор «цифр». И у у такого же накопителя была проблема, которую легко решить, изменив базу входных чисел на выходные числа .

2 голосов
/ 03 июня 2011

Использование шестнадцатеричного кода просто облегчает отображение.SHA1 использует 160 бит.За счет шестнадцатеричного кодирования он позволяет легко отображать дайджест и переносить его в виде строки.Вот и все.

2 голосов
/ 03 июня 2011

Это ложное рассуждение. sha1 использует 40 * 4 = 160 бит.

Просто удобно (и, следовательно, соглашение) форматировать это как 40 шестнадцатеричных цифр.

Вы можете использовать разные криптографические хеши с большим размером хэша, если вы чувствуете, что находитесь в проблемной области, где коллизии начинаются с вероятностью в 160 бит

 sha224: 224 bits
 sha256: 256 bits
 md5: 128 bits
1 голос
/ 03 июня 2011

sha-1 создает 160-битный хеш, то есть 20 байтов, который имеет 1461501637330902918203684832716283019655932542976 возможных значений.Потому что так определяется алгоритм хеширования.

Тем не менее, часто бывает полезно кодировать этот хэш как читаемый текст, и удобный способ - просто закодировать эти 20 байтов в шестнадцатеричный формат (который займет 40 байтов).И шестнадцатеричные символы [a-f0-9].

1 голос
/ 03 июня 2011

Выходные данные алгоритма хеширования являются битами. Представлять их в шестнадцатеричном виде - это просто представление. Получается преимущество от результата длины 0 mod 16, поэтому представление в базе 17 будет неудобным.

...