помогите с md5

 

BrAB

аксакал
★☆
свалилась задача - написать хеш-функцию по алгоритму md5. ну вроде ничего сложного - качаю rfc1231 читаю и алга.
Но потом пошли страности. Вот что непонятно:
В стандарте приведены следующие значения инициализации:

Ответ: 01 23 45 67
B: 89 ab cd ef
C: fe dc ba 98
D: 76 54 32 10

Однако в других описаниях и самое главное во всех нарытых исходниках стоят другие числа, а именно
A = 0x67452301
B = 0xEFCDAB89
C = 0x98BADCFE
D = 0x10325476

Так что непонятно, что собственно использовать. далее вопрос по формированию исходной последовательности. Вот есть у нас символ a (код 97). чтобы вычислить его хеш получаем:
нулевой байт - 97
первый байт - 128 (добавляем сначала 1 потом нули)
потом идут нулевые байты
предпоследнее слово равно 8 - длине исходного сообщения в битах.
последнее - снова нулевое.
Правильно ли я написал или нет?

И ещё - как можно отладить эту штуку и найти ошибку? ведь промежуточные результаты взять негде, я могу сравнивать только конечный результат....

Всем заранее спасибо.
Было у еврея всё плохо. Пришел за советом к равину. Тот - напиши над дверью - "Так будет не всегда". Стало всё ок. Пошел он благодарить. А тот ему - надпись не стирай. Злой чечен ползет на берег. ©Лермонтов  

ceci_

втянувшийся


BrAB>A: 01 23 45 67
BrAB>B: 89 ab cd ef
BrAB>C: fe dc ba 98
BrAB>D: 76 54 32 10
BrAB>Однако в других описаниях и самое главное во всех нарытых исходниках стоят другие числа, а именно
BrAB>A = 0x67452301
BrAB>B = 0xEFCDAB89
BrAB>C = 0x98BADCFE
BrAB>D = 0x10325476

Стандарт пока не смотрел, но на первь!й взгляд числа одинаковь!е, просто думаю что в стандарте и в изходниках нулевой байт считается с разнь!х сторо. В одном случае нулевой бит с правой а в другом с левой сторонь!.
 

Mishka

модератор
★★☆

BrAB>>A: 01 23 45 67
BrAB>>B: 89 ab cd ef
BrAB>>C: fe dc ba 98
BrAB>>D: 76 54 32 10
BrAB>>Однако в других описаниях и самое главное во всех нарытых исходниках стоят другие числа, а именно
BrAB>>A = 0x67452301
BrAB>>B = 0xEFCDAB89
BrAB>>C = 0x98BADCFE
BrAB>>D = 0x10325476
ceci_>Стандарт пока не смотрел, но на первь!й взгляд числа одинаковь!е, просто думаю что в стандарте и в изходниках нулевой байт считается с разнь!х сторо. В одном случае нулевой бит с правой а в другом с левой сторонь!.[»]

Ага. Это проблема Big Endian / Little Endian. В RFC-ях, как правило, используется BE - таков сетевой стандарт (для BE, смотри IBM/360, например). А в других местах - как правило LE.

Разница между ними такова, что в BE наиболее значимые байты идут раньше (меньшие адреса), а в LE наименее значимые байты идут раньше.

Скажем, число 513 будет представлено в памяти IBM/360 как 32-х разрядное целое в виде 0х00000201, а в памяти ПС-шки, как 0х01020000.
 

BrAB

аксакал
★☆
Уф! спасибо разобрался.

Всплыл другой вопрос - как возвести очень большое (128 бит) число в большую степень? делать в цикле умножения столбиком не хочется :(
Было у еврея всё плохо. Пришел за советом к равину. Тот - напиши над дверью - "Так будет не всегда". Стало всё ок. Пошел он благодарить. А тот ему - надпись не стирай. Злой чечен ползет на берег. ©Лермонтов  

Balancer

администратор
★★★★☆
BrAB>Всплыл другой вопрос - как возвести очень большое (128 бит) число в большую степень? делать в цикле умножения столбиком не хочется :([»]

Если требуется точное вычисление, а не с плавучкой, то только так. Ну, разве что немного оптимизировать:
code cpp
  1. #include <iostream.h>
  2. void main()
  3. {
  4.       int x,y;
  5.       int odd(int);
  6.       /* --------------------------------- */
  7.       cout << "Введите x, y: ";
  8.       cin >> x >> y;
  9.       int a = x, b = y, z = 1;
  10.       while (b!=0)
  11.          if  (odd(b))
  12.          {
  13.             z *= a; b--;
  14.          }
  15.          else
  16.          {
  17.             a *= a; b /= 2;
  18.          }
  19.        cout << z << endl;
  20. }
  21. /* ------- */
  22. int odd (int t)
  23. {
  24.       return (t%2==0)?0:1;
  25. }
 
+
-
edit
 

Balancer

администратор
★★★★☆
Идею оптимизации возведения числа в любую целочисленную(!) степень проще показать на примере: a25=a16 * a8 * a1 где a16 = a8 * a8 и тд. При этом 16,8,1 - это соответствующие биты двоичного разложения числа 25. Таким образом, для возведения в степень 25 надо выполнить всего 6 умножений: одно для a2 + одно для a4=a2*a2 + одно
для a8=a4*a4 + одно для a16=a8*a8 + два для получения окончательного результата. А если хочешь возвести в степень без умножений - то замени их сложениями -).

// Выпуск рассылки "Вопросы и ответы по С и С++" от 19 января 2003 года. Рассылки @MAIL.RU: Служба почтовых рассылок
 
 
+
-
edit
 

Mishka

модератор
★★☆

Ром, там есть подводные камни - надо произвольное число (в нашем случае, 128 битное) в произвольную степень (подозреваю, что тоже 128).

 

ceci_

втянувшийся

BRaB только что смотрел 3poxy, там есть простенькая реализация / в смь!сле объема/ реализаия md5 можеш посмотреть так что к чему :)
 
ceci_>BRaB только что смотрел 3poxy, там есть простенькая реализация / в смь!сле объема/ реализаия md5 можеш посмотреть так что к чему :)[»]

Всем спасибо, с md5 разобрался. смена последовательности байт меня просто убила - но теперь всё считает :).

А вот с умножением буду думать. Там действительно 128 в 128 :)
 

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru