Проверка, является ли строка sha1 в PHP

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

Спасибо

Изменить: я не пытаюсь увидеть, совпадают ли два хэша.


person Leagsaidh Gordon    schedule 05.06.2010    source источник
comment
Большинство людей хранят хэш sha1, а затем, когда вам нужно проверить пароль, если он такой же, получить sha1 нового пароля и сравнить его с сохраненным, они должны быть такими же. Я предположил, что это то, чего вы пытаетесь достичь.   -  person animuson    schedule 06.06.2010
comment
Если вы действительно хотите «сопоставить» хэши sha1, см. Здесь: stackoverflow.com/questions/468370/a-regex-to-match-a-sha1   -  person miku    schedule 06.06.2010
comment
Все, что вы можете сделать, это проверить несколько действительно основных моментов, таких как содержание 160 бит информации в том формате, который вы предпочитаете (например, шестнадцатеричные цифры). Контент - это совсем другая история - можно надеяться, что можно сгенерировать все возможные выходные данные (и, я считаю, что это так), что означает, что любое значение может быть действительным.   -  person Jerry Coffin    schedule 06.06.2010


Ответы (3)


Фактически, вы можете использовать preg_match(), чтобы убедиться, что это шестнадцатеричная строка из 40 символов как таковая:

function is_sha1($str) {
    return (bool) preg_match('/^[0-9a-f]{40}$/i', $str);
}

Чтобы объяснить закономерность:

/        Opening Delimiter
^        Start Of String Anchor
[0-9a-f] Any of the following characters: 0123456789abcdef
{40}     Repeated 40 times
$        End Of String Anchor
/        Closing Delimiter
i        Modifier: Case-Insensitive Search


Если вы пытаетесь убедиться, что хеш sha1() совпадает с паролем пользователя-провайдера, вы просто перефразируете следующим образом:

if($db_hash == sha1($user_provided_pass))
   echo "Password is correct!";
person Andrew Moore    schedule 05.06.2010
comment
Спасибо. Вы не только дали мне нужный шаблон, но и объяснили, что означает каждый бит. - person Leagsaidh Gordon; 06.06.2010
comment
Или вы можете использовать ctype_xdigit (только для проверки шестнадцатеричных цифр) и _ 2_ (для проверки длины строки). - person salathe; 06.06.2010
comment
Нет необходимости в нечувствительном тесте. - person StackSlave; 06.08.2020
comment
Также соответствует всем алгоритмам * 160 и одному в миллионов шансов, что входные данные соответствуют регулярному выражению без фактического хеширования. Используйте password_hash() для паролей, так как хэши автоматически подслаиваются. - person zanderwar; 15.06.2021

ctype_xdigit намного быстрее. Я обычно использую хеши для поиска и считаю это очень полезным.

person Kristopher Ives    schedule 09.05.2012

При сравнении двух хэшей SHA1 и вы знаете, что первый является одним (потому что он исходит из базы данных), тогда просто предположите, что второй также является значением SHA1. Вас интересует только совпадение двух хешей. Если одно из сравниваемых значений не является возможным значением SHA1, то оно, в частности, не совпадает с значением в базе данных. И это все, что вам нужно знать.

person poke    schedule 05.06.2010
comment
Я знаю, что это старый пост, но хотел добавить к нему свой комментарий. Что если вы, передавая sha1 через URL-адрес в виде строки, представляете, например, MVC или передаете пароль через AJAX POST / GET, вы можете захотеть преобразовать строку в SHA1 или MD5 или что-то еще до того, как получить сообщение (или put), потому что вы никогда не знаете, когда кто-то перехватывает пакеты или делает что-то, чтобы перехватить опубликованные пароли в виде простого текста - person chris; 06.10.2011
comment
(Я даже не помню этот вопрос o.O) Если вы хешируете пароль перед отправкой его на сервер, вы ничего не получите. Поскольку, как только сервер уже принимает хешированное значение, сам хеш работает как пароль. Так что кто-то может легко обнюхать пакеты и получить отправленный хэш и использовать его так же, как обычно используют текстовый пароль. Решение состоит не в том, чтобы зашифровать (или хэшировать) пароль перед отправкой, а в том, чтобы обеспечить безопасность самой связи (например, через SSL). - person poke; 06.10.2011
comment
извините, что копаю старые воспоминания :-) Вы правы в большей степени, когда упоминаете SSL, но это только если вы предполагаете, что просто отправляемый прямой хеш - это пароль, используемый для сравнения. Лично я использую простой текст sha1 / md5 либо один, либо другой, а затем имею другое совершенно уникальное и случайное значение соли, которое было создано и сохранено с хешем пароля, изначально созданным, с которым я повторно хеширую. Эта соль никогда не видна никому, кроме кода на стороне сервера. - person chris; 07.10.2011