Попытка расшифровать класс PHP PseudoCrypt

Я пытаюсь создать способ обратить вспять сценарий PseudoCrypt, указанный по адресу: http://blog.kevburnsjr.com/php-unique-hash. В этом коде оно имеет следующее уравнение:

$dec = ($num * $prime)-floor($num * $prime/$ceil)*$ceil;

Мне удалось получить все переменные, кроме $num. Например, возьмите следующие цифры:

$dec = 566201239;
$prime = 566201239;
$ceil = 916132832;

Тогда уравнение будет выглядеть так:

566201239 = ($num * 566201239)-floor($num * 566201239/916132832)*916132832;

Ответ должен быть 1. Однако я не определил способ сделать уравнение = $num. Я хочу использовать хеш, который он создает в URL, а затем расшифровать хеш для выполнения запросов в моей базе данных.

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

Редактировать: Каким-то образом я добавил неправильное значение для $dec. Изменить: публикация в блоге обновлен с функциональным кодом.

3 ответа

Решение

Благодаря некоторой помощи от комментатора Padraig Kennedy, библиотека была обновлена ​​для поддержки обратимости
http://blog.kevburnsjr.com/php-unique-hash

Соблюдайте это

вещь - пол (вещь / потолок) * потолок

то же самое, что (thing% Ceil), где% - оператор по модулю (остаток после деления). В твоем случае,

$ dec = ($ num * $prime)% $ ceil

Обратите внимание, что это всегда между 0 и $ ceil-1, поэтому значение $ dec, которое вы имеете, равное $ ceil, не может быть получено. С другой стороны, для данного $ dec между 0 и $ ceil-1 вы можете эффективно найти решение $ num между 0 и $ ceil-1.

(Наблюдение состоит в том, что если $ num является решением, то $ num + i * $ ceil для любого i также является решением.)

Вот как вы поступаете за $ dec = 42.

Мы будем использовать тот факт, что $ ceil = 2 ^ 5 * 31 ^ 5. Таким образом, уравнение дает

42 = ($ num * 566201239)% (2 ^ 5 * 31 ^ 5)

Сначала давайте найдем ($ num% 2), другими словами, является ли $ num нечетным или четным. Мы берем обе части уравнения по модулю 2:

0 = 42% 2 = (($ num * 566201239)% (2 ^ 5 * 31 ^ 5))% 2.

Поскольку 2 делит $ ceil, правая часть равна ($ num * 566201239)% 2. Если это должно быть 0, $ num должен быть четным (так как $prime - нет). Таким образом, мы имеем ($ num = 2 * $ a) для некоторого $ a и

2 * 21 = 42 = (2 * $ a * 566201239)% (2 ^ 5 * 31 ^ 5),

после деления на 2 получаем

21 = ($ a * 566201239)% (2 ^ 4 * 31 ^ 5).

Обратите внимание, что часть после знака% также была разделена на 2. Мы продолжим, взяв это по модулю 2. Получим, что $ a нечетно, т. Е. $ A = 2*$b+1 для некоторого $ b.

21 = ((2 * $ b + 1) * 566201239)% (2 ^ 4 * 31 ^ 5),

349931614 21-566201239 ≡ (2 * $ b * 566201239)% (2 ^ 4 * 31 ^ 5),

(Я начал использовать конгруэнтную запись ≡; под x ≡ y % z я подразумеваю x% z = y% z).

174965807 ≡ ($ b * 566201239)% (2 ^ 3 * 31 ^ 5)

Мы продолжаем...

174965807 ≡ ((2 * $ c + 1) * 566201239)% (2 ^ 3 * 31 ^ 5)

174965807 - 566201239 ≡ (2 * $ c * 566201239)% (2 ^ 3 * 31 ^ 5)

66830984 ≡ 2 * $ c * 566201239)% (2 ^ 3 * 31 ^ 5)

33415492 ≡ ($ c * 566201239)% (2 ^ 2 * 31 ^ 5)

33415492 ≡ (2 * $ d * 566201239)% (2 ^ 2 * 31 ^ 5)

16707746 ≡ ($ d * 566201239)% (2 * 31 ^ 5)

16707746 ≡ (2 * $ e * 566201239)% (2 * 31 ^ 5)

8353873 ≡ ($ e * 566201239)% (31 ^ 5).

Чтобы подвести итог замен, напомним, что

$num = 2*$a = 2*(2*$b+1) = 4*$b+2 = 4*(2*$c+1)+2 = 8*$c+6 = 8*2*$d+6 = 8*2*2*$e+6 = 32*$e + 6

Кстати, мы можем также уменьшить $prime в уравнении по модулю 31 ^ 5 (мы можем продолжать уменьшать его на текущий модуль на каждом шаге, но кого это волнует?):

8353873 ≡ ($ e * 22247370)% (31 ^ 5).

Мы можем видеть, что множитель не является простым, но на самом деле это не имеет значения.

Теперь посмотрим на последнее уравнение по модулю 31.

8353873 ≡ ($ e * 22247370)% (31 ^ 5).

24 8353873 73 ($ e * 22247370)% (31 ^ 5) ≡ ($ e * 22247370) ≡ ($ e * 3)% 31

В таблице поиска, кратной 3 по модулю 31, мы находим, что $ e≡8% 31 или $ e = 31 * $ f + 8:

8353873 ≡ ((31 * $ f + 8) * 22247370)% (31 ^ 5).

8353873 - 8*22247370 ≡ (31 * $ f * 22247370)% (31 ^ 5).

2149819,8353873 - 8*22247370 (31 * $ f * 22247370)% (31 ^ 5).

69349 = 2149819/31 ≡ ($ f * 22247370)% (31 ^ 4)

и мы продолжаем...

2 69349% 31 ≡ ($ f * 22247370)% (31 ^ 4) ≡ ($ f * 3)% 31

$ f ≡ 11% 31

$ f = 31 * $ g + 11

69349 ≡ ((31 * $ г + 11) * 22247370)% (31 ^ 4)

81344 69349 - 11 * 22247370 ≡ (31 * $ г * 22247370)% (31 ^ 4)

2624 ≡ ($ г * 22247370)% (31 ^ 3)

Давайте снова уменьшим множитель...

2624 ≡ ($ г * 23284)% (31 ^ 3)

20 2624 ≡ ($ г * 23284)% (31 ^ 3) = ($ г * 3)% 31

$ g = 31 * $ h + 17

2624 ≡ ((31 * $ ч + 17) * 23284)% (31 ^ 3)

23870 24 2624 - 17 * 23284 ≡ (31 * $ ч * 23284)% (31 ^ 3)

770 ≡ ($ ч * 23284)% (31 ^ 2)

26 70 770 ≡ ($ ч * 23284)% (31 ^ 2) = ($ ч * 3)% 31

$ h = 31 * $ i + 19

770 ≡ ((31 * $ i + 19) * 23284)% (31 ^ 2)

434 770 - 19 * 23284 (31 * $ i * 23284)% (31 ^ 2)

14 = ($ i * 3)% 31

$ я = 15

и путем обратной замены мы получаем $ h = 31 * 15 + 19 = 484, $ g = 31 * $ h + 17 = 15021, $ f = 31 * $ g + 11 = 465662, $ e = 31 * $ f + 8 = 14435530, $ num = 32 * e + 6 = 461936966.

Осталось просто проверить результат:

. >>> (461936966 * 566201239)% 916132832

42

Вот Это Да!:-)

Парень из блога должен был использовать md5.

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

Другие вопросы по тегам