У меня есть сценарий для преобразования в базу 62 (A-Za-z0-9), но как мне получить номер из MD5?
Я читал во многих местах, что, поскольку число из MD5 больше, чем php, может обрабатывать как целое число, оно будет неточным … Так как я хочу короткий URL-адрес в любом случае и не планировал использовать весь хэш, возможно, всего 8 символов из этого ….
Итак, мой вопрос заключается в том, как получить часть количества хэшей MD5?
Также неплохо ли использовать только часть хэша MD5?
Я собираюсь предложить другое дело здесь. Поскольку вы заинтересованы только в использовании десятичного фрагмента хеша md5, почему бы вам не использовать какой-либо другой короткий хэш, например CRC32 или Adler ? Вот пример:
$hash = sprintf('%u', crc32('your string here'));
Это приведет к 8-значному хэшу вашей строки.
EDIT: Я думаю, что я вас неправильно понял, вот некоторые функции, которые обеспечивают конверсии на и от баз до 62 .
EDIT (снова) : для работы с произвольными номерами длины вы должны использовать либо bc_math, либо расширение GMP, вот функция, которая использует расширение bc_math, а также может конвертировать из базы 2 в базовую 62 . Вы должны использовать его следующим образом:
echo bc_base_convert(md5('your url here'), 16, 62); // public base 62 hash
и наоборот:
echo bc_base_convert('base 62 encoded value here', 62, 16); // private md5 hash
Надеюсь, поможет. знак равно
Если это возможно, я бы посоветовал не использовать хэш для ваших URL-адресов. В конце концов вы столкнетесь с конфликтами … особенно если вы усекаете хэш. Если вы продвигаетесь вперед и внедряете систему на основе идентификатора, где каждый элемент имеет уникальный идентификатор, будет гораздо меньше головных болей. Первый элемент будет 1
, второй – 2
и т. Д. — если вы используете MySQL, просто введите столбец автоинкремента.
Чтобы сделать короткий идентификатор:
//the basic example $sid = base_convert($id, 10, 36); //if you're going to be needing 64 bit numbers converted //on a 32 bit machine, use this instead $sid = gmp_strval(gmp_init($id, 10), 36);
Чтобы сделать короткий идентификатор обратно в base-10 id:
//the basic example $id = base_convert($id, 36, 10); //if you're going to be needing 64 bit numbers //on a 32 bit machine, use this instead $id = gmp_strval(gmp_init($shortid, 36));
Надеюсь это поможет!
Если вам действительно нужна база 62 (что нельзя сделать с помощью gmp
или base_convert
), проверьте это: http://snipplr.com/view/22246/base62-encode–decode/
Вы можете сделать это следующим образом: (Не все шаги в php, я давно использовал это.)
Создайте хеш-файл md5 для скрипта следующим образом:
$ hash = md5 (script, raw_output = true);
Преобразуйте это число в базу 62.
См. Вопросы о преобразовании базы произвольных размеров в PHP
Усекайте строку до требуемой длины.
Нет никакого риска использовать только несколько бит md5. Все, что меняется, – опасность столкновений.
Вы можете использовать слегка модифицированную Base 64 с -
и _
вместо +
и /
:
function base64_url_encode($str) { return strtr(base64_encode($str), array('+'=>'-', '/'=>'_')); } function base64_url_decode($str) { return base64_decode(strtr($str, array('-'=>'+', '_'=>'/'))); }
Кроме того, вы можете удалить завершающие пробелы =
символы.
И чтобы получить исходное значение MD5 (двоичная строка), установите второй параметр (с именем $raw_output
в руководстве) в true :
$raw_md5 = md5($str, true);
Вы можете сделать что-то подобное,
$hash = md5("The data to be hashed", true); $ints = unpack("L*num", $hash); $hash_str = base62($ints['num1']) . base62($ints['num2']) . base62($ints['num3']) . base62($ints['num4'])
Начиная с PHP 5.3.2, GMP поддерживает базы до 62 (ранее было только 36), поэтому предложение Брианреависа было очень близким. Я думаю, что самый простой ответ на ваш вопрос:
function base62hash($source, $chars = 22) { return substr(gmp_strval(gmp_init(md5($source), 16), 62), 0, $chars); }
Переход от базового 16 к базовому-62, очевидно, имеет преимущества в космосе. Обычный 128-битный MD5-хэш составляет 32 символа в шестнадцатеричном формате, но в базе-62 это всего лишь 22. Если вы храните хэши в базе данных, вы можете преобразовать их в необработанный двоичный файл и сохранить еще больше места (16 байт для MD5).
Поскольку полученный хеш – это просто строковое представление, вы можете просто использовать substr, если хотите только немного его (как это делает функция).
На самом деле есть реализация Java, которую вы могли бы извлечь. Это CMS с открытым исходным кодом под названием Pulse.
Посмотрите здесь код toBase62()
и fromBase62()
.
http://pulse.torweg.org/javadoc/src-html/org/torweg/pulse/util/StringUtils.java.html
Единственная зависимость в StringUtils
– это класс LifeCycle, который предоставляет способ получить соленый хеш для строки, которую вы можете даже опустить вместе или просто скопировать метод на свою копию StringUtils
. Вуаля.
Вы можете попробовать base62x получить безопасное и совместимое кодированное представление.
Для получения дополнительной информации о base62x или просто -base62x
в -NatureDNS
.
shell> ./base62x -n 16 -enc 16AF 1Ql shell> ./base62x -n 16 -dec 1Ql 16AF shell> ./base62x Usage: ./base62x [-v] [-n <2|8|10|16|32>] <-enc|dec> string Version: 0.60