- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
def constant_time_compare(val1, val2):
"""
Returns True if the two strings are equal, False otherwise.
The time taken is independent of the number of characters that match.
"""
if len(val1) != len(val2):
return False
result = 0
for x, y in zip(val1, val2):
result |= ord(x) ^ ord(y)
return result == 0
Dummy00001 24.10.2014 12:51 # −1
roman-kashitsyn 24.10.2014 12:59 # −1
Qwertiy 24.10.2014 13:02 # −1
3.14159265 24.10.2014 13:05 # −1
Вообще охуеть. Не совпало в первом символе гигабайтной строки.
А прочитаешь, на первый взгляд вроде как улучшение: алгоритм не зависит от некоего M.
Жаль питонистам еще брейки не завезли.
Qwertiy 24.10.2014 13:19 # +7
utils.crypto же!
Это функция для сравнения всяких ключей и паролей. Надо сравнивать все символы, чтобы было невозможно использовать время работы функции для определения числа правильных символов при переборе.
Но косяк в ней всё равно есть. Если длины разные, то значение возвращается сразу.
bormand 24.10.2014 13:50 # 0
Да и хер с ним, если честно. Хакер, скорее всего, и без этого знает, что там какой-нибудь sha-256 длиной 256 бит.
bormand 24.10.2014 13:47 # −1
wvxvw 24.10.2014 18:34 # 0
3.14159265 24.10.2014 18:37 # 0
Об этом и речь. Надо проверить как можно быстрее, и только если НЕ совпало - поставить sleep/сделать N итераций чтоб получилось фиксированное.
Тут где-то уже обсуждали на примере линуксов.
guest 31.12.2014 04:05 # +1
Почему?
>Все равно это не константное время. Оно прямо зависит от количества символов в строке.
Оно не зависит от позиции первого несовпадающего символа, я хз как это правильно записать.
roman-kashitsyn 31.12.2014 09:56 # 0
Θ(n)
chtulhu 24.10.2014 13:19 # +3
Для криптографических задач важно, чтобы данные проверялись одинаковое время и хакер не мог с помощью статистики быстро подобрать токены, пароли итд
Lure Of Chaos 24.10.2014 14:46 # 0
3.14159265 24.10.2014 18:25 # −1
Вы или O(N) снимите или crypto наденьте. Константным временем там и пахнет.
bormand 24.10.2014 18:39 # +1
Пароли сравнивать - хреновая идея (т.к. подразумевает хранение пароля в открытом или обратимо зашифрованном виде). А сравниваться будут, скорее всего, какие-нибудь хеши или рандомные блоки известной и постоянной (ну ок, зависящей от настроек) длины. Время тут константное в том смысле, что оно зависит только от этой константной длины, но никак не зависит от значений бит в самих строках.
Dummy00001 24.10.2014 21:55 # +1
но все равно ахинея. время сравнения скажем 256 бит хэшей (== 32 байта), тем более на современном железе, незначительно и сравнимо, например, с временем выполнения пролога/эпилога функции. вкинь один быстрый syscall и о длине совпадающих символом можно только гадать на картах.
wvxvw 24.10.2014 23:50 # −1
inkanus-gray 25.10.2014 01:00 # −1
bormand 25.10.2014 07:23 # −1
bormand 25.10.2014 07:20 # −1
Да не должны быть они интернированы... Это же довольно дорогая операция, и память жрёт. Часть строк - запросто может. Но никак не все.
wvxvw 25.10.2014 08:09 # −1
bormand 25.10.2014 08:24 # 0
Но не нужно. В чем смысл интернировать всё подряд, включая временные переменные, которые живут пару функций, и никто никогда не будет их сравнивать?
Для литералов это имеет смысл. Для остальных строк - нет.
wvxvw 25.10.2014 08:24 # −1
bormand 25.10.2014 08:27 # −1
> отнимает время при создании
Именно.
wvxvw 25.10.2014 08:32 # −1
bormand 25.10.2014 08:35 # −1
wvxvw 25.10.2014 08:37 # −1
Другими словами: нахера такие хеш-таблицы вообще нужны, если из них нельзя получить то, о чем так долго говорили большевики? Деревья будут предпочтительнее всегда.
bormand 25.10.2014 08:39 # −1
O(1) от количества записей в таблице. Но O(M) от длины строк-ключей (расчет хеша, допроверка для борьбы с коллизиями).
> Деревья будут предпочтительнее всегда.
А у деревьев еще больше сравнений. Так что не всегда.
> нахера такие хеш-таблицы вообще нужны
Ну хеш-таблицы ведь далеко не везде юзают. К примеру, в реалтаймовых приложениях, вставка в дерево за log(N) может быть предпочительней амортизированного O(1) у хеш табличек. Для огромных дисковых структур, не влезающих в память, деревья тоже предпочительней.
wvxvw 25.10.2014 08:46 # −1
Интернированые строки нужно хранить в структуре с быстрым доступом - а остальные объекты не нужно? Если это делается на уровне языка, а не силами добровольцев, то на памяти это вообще никак не отразится. Примеры: V8 (NodeJS) и Луа. И ничего, живут как-то.
3.14159265 25.10.2014 20:36 # −1
3.14159265 25.10.2014 20:48 # −1
> Чтобы сгенерировать хеш, нужно прочитать всю строку целиком.
На коротких строках, с которые обычно встречаются на практике в виде ключей это не сильно ощутимо.
Если же смотреть контексте интернирования, то тут выгоднее повторно использовать ссылки на строки большей длины.
Ну и если строка немутабельная, то посчитать хеш придется всего 1 раз, и таким образом за O(1) проверять отсутствие строки в кеше. А ведь можно сделать и джва хеша, что прилично снизит вероятность полного сопоставления.
Кстати мы не так давно тут с Тарасом обсуждали префиксные деревья.
guest 25.10.2014 21:23 # 0
Орально обсуждали?
anonimb84a2f6fd141 25.10.2014 23:37 # −3
>>Очко сильно раздолбано
>>Орально обсуждали
Не, это не в стиле Тараса. Непохоже на него.
3.14159265 25.10.2014 20:37 # −1
Анонимус 06.11.2014 04:26 # +2
"""
Returns True if the two strings are equal, False otherwise.
The time taken is independent of the number of characters that match.
"""
time.sleep(random(500))
return val1==val2
anonimb84a2f6fd141 25.10.2014 23:41 # −3