Ну, каждый символ md5
- это шестнадцатеричный бит.Это означает, что он может иметь одно из 16 возможных значений.Таким образом, если вы используете только первые 4 "шестнадцатеричных бита", это означает, что вы можете иметь 16 * 16 * 16 * 16
или 16^4
или 65536 или 2^16
возможности.
Таким образом, это означает, что общее доступное «пространство» для результатов составляет всего 16 бит в ширину.Теперь, согласно Атака на день рождения / Проблема , есть следующие шансы на столкновение:
50%
шанс -> 300
записей 1%
шанс -> 36
записей 0.0000001%
шанс -> 2
записей.
Так что вероятность столкновений довольно высока.
Теперь вы говорите, что вам нужен хэш из 4 символов.В зависимости от конкретных требований вы можете сделать:
- 4 шестнадцатеричных бита для
16^4
(65 536) возможных значений - 4 альфа-бита для
26^4
(456 976) возможных значений - 4 буквенно-цифровых бита для
36^4
(1 679 616) возможных значений - 4 ascii печатных бита для примерно
93^4
(74 805 201) возможных значений (при условии ASCII 33 -> 126) - 4 полных байта для
256^4
(4 294 967 296) возможных значений.
Теперь то, что вы выберете, будет зависеть от фактического варианта использования.Нужно ли передавать хеш в браузер?Как вы храните его и т. Д.
Я приведу пример каждого из них (на PHP, но должно быть легко перевести / посмотреть, что происходит):
4 Hex-Биты :
$hash = substr(md5($data), 0, 4);
4 буквенных разряда :
$hash = substr(base_convert(md5($data), 16, 26)0, 4);
$hash = str_replace(range(0, 9), range('S', 'Z'), $hash);
4 буквенно-цифровых разряда :
$hash = substr(base_convert(md5($data), 16, 36), 0, 4);
4 бита Assci для печати :
$hash = hash('md5', $data, true); // We want the raw bytes
$out = '';
for ($i = 0; $i < 4; $i++) {
$out .= chr((ord($hash[$i]) % 93) + 33);
}
4 полных байта :
$hash = substr(hash('md5', $data, true), 0, 4); // We want the raw bytes