Алгоритм MD2

Добрый день.

Писал свою реализацию алгоритма MD2 (лабораторная такая). Но вот почему-то контрольные тесты не совпадают с теми, что в RFC и википедии (делал по википедии: http://ru.wikipedia.org/wiki/MD2). В чем может быть проблема?

Код md2.h
#ifndef MD2_H
#define MD2_H

#include <QString>

class MD2
{
private:
   static qint8 PI_SUBST[];
public:
   MD2();
   static QString calculate(QString input);
};

#endif // MD2_H

Код md2.cpp
#include "md2.h"
#include <QDebug>

qint8 MD2::PI_SUBST[] = {
   41,  46,  67, 201, 162, 216, 124,   1,  61,  54,  84, 161, 236, 240,   6,  19,
   98, 167,   5, 243, 192, 199, 115, 140, 152, 147,  43, 217, 188,  76, 130, 202,
   30, 155,  87,  60, 253, 212, 224,  22, 103,  66, 111,  24, 138,  23, 229,  18,
  190,  78, 196, 214, 218, 158, 222,  73, 160, 251, 245, 142, 187,  47, 238, 122,
  169, 104, 121, 145,  21, 178,   7,  63, 148, 194,  16, 137,  11,  34,  95,  33,
  128, 127,  93, 154,  90, 144,  50,  39,  53,  62, 204, 231, 191, 247, 151,   3,
  255,  25,  48, 179,  72, 165, 181, 209, 215,  94, 146,  42, 172,  86, 170, 198,
   79, 184,  56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116,   4, 241,
   69, 157, 112,  89, 100, 113, 135,  32, 134,  91, 207, 101, 230,  45, 168,   2,
   27,  96,  37, 173, 174, 176, 185, 246,  28,  70,  97, 105,  52,  64, 126,  15,
   85,  71, 163,  35, 221,  81, 175,  58, 195,  92, 249, 206, 186, 197, 234,  38,
   44,  83,  13, 110, 133,  40, 132,   9, 211, 223, 205, 244,  65, 129,  77,  82,
  106, 220,  55, 200, 108, 193, 171, 250,  36, 225, 123,   8,  12, 189, 177,  74,
  120, 136, 149, 139, 227,  99, 232, 109, 233, 203, 213, 254,  59,   0,  29,  57,
  242, 239, 183,  14, 102,  88, 208, 228, 166, 119, 114, 248, 235, 117,  75,  10,
   49,  68,  80, 180, 143, 237,  31,  26, 219, 153, 141,  51, 159,  17, 131,  20};

MD2::MD2()
{
}

QString MD2::calculate(QString input)
{
   QByteArray input_array(input.toUtf8());
   qDebug() << input_array;

   qint8 i = 0;
   qint32 length = input_array.length();
   if(length%16 == 0)
       i = 16;
   else
       i = 16 - length%16;

   qDebug() << i;
   qDebug() << input_array.length();

   input_array.resize(length + i);

   qDebug() << input_array.length();
   qDebug() << input_array;

   for(qint32 j = length;j<length+i;j++)
   {
       input_array[j] = i;
   }

   length += i;

   QByteArray C;
   C.resize(16);

   for(int i = 0;i<16;i++)
       C[i] = 0;

   qint32 L = 0;

   for(qint32 i = 0;i<length/16;i++)
   {
       for(qint8 j = 0;j<16;j++)
       {
           qint32 c = input_array[i*16+j];
           C[j] = C[j] ^ PI_SUBST[c ^ L];
           L = C[j];
       }
   }

   qDebug() << C;

   input_array.append(C);

   length = input_array.length();

   qDebug() << input_array;
   qDebug() << input_array.length();

   QByteArray X;
   X.resize(48);

   for(qint8 i = 0;i<48;i++)
       X[i] = 0;

   for(qint32 i = 0;i<length/16;i++)
   {
       for(qint8 j = 0;j<16;j++)
       {
           X[16+j] = input_array[i*16+j];
           X[32+j] = (X[16+j] xor X[j]);
       }

       qint32 t = 0;

       for(qint8 j = 0;j<18;j++)
       {
           for(qint8 k = 0;k<48;k++)
           {
               t = (X[k] ^ PI_SUBST[t]);
               X[k] = (X[k] ^ PI_SUBST[t]);
           }

           t = (t+j)%256;
       }
   }

   QByteArray output_array;
   output_array.resize(16);

   QString output;

   for(qint8 i = 0;i<16;i++)
   {
       output_array[i] = X[i];
       output.append(X.at(i));
   }

   return output_array.toHex();
}

0
Гость - 16 Февраль, 2011 - 08:26

md2.cpp
очевидная ошибка.
даже кушать не могу.

0
ktchv - 16 Февраль, 2011 - 13:15
Изображение пользователя ktchv.

может дело в переводе в utf8? может попробовать простую строчку?
(сам алгоритм не смотрел)

0
Гость - 16 Февраль, 2011 - 13:35

Пробовал уже и toAscii -- хеш отличается от этого, но все равно неправильный.

0
ktchv - 16 Февраль, 2011 - 14:16
Изображение пользователя ktchv.

может дополняешь массив не так? сравни с кодом из rfc

+2
_KoT_ - 16 Февраль, 2011 - 18:14
Изображение пользователя _KoT_.

Алгоритм MD2 я не знаю, но просто по коду:
Вместо QByteArray input_array(input.toUtf8()); надо QByteArray input_array((char*)(input.utf16()), input.size() * 2); // ushort — 2 char У меня иначе в масив попадал только кусок строки.

Вместо     qint8 i = 0;
    qint32 length = input_array.length();
    if(length%16 == 0)
        i = 16;
    else
        i = 16 - length%16;
достаточно     qint32 length = input_array.length();
    qint8 i = 16 - length%16;
16 - 0 равно 16 ;)

Вместо     QByteArray C;
    C.resize(16);

    for(int i = 0;i<16;i++)
        C[i] = 0;
лаконичней     QByteArray C(16, 0); http://doc.crossplatform.ru/qt/4.7.x/qbytearray.html#QByteArray-4

0
_KoT_ - 16 Февраль, 2011 - 17:53
Изображение пользователя _KoT_.

    QByteArray X;
    X.resize(48);

    for(qint8 i = 0;i<48;i++)
        X[i] = 0;
тоже самое

0
_KoT_ - 16 Февраль, 2011 - 18:12
Изображение пользователя _KoT_.

    QByteArray output_array;
    output_array.resize(16);

    QString output;

    for(qint8 i = 0;i<16;i++)
    {
        output_array[i] = X[i];
        output.append(X.at(i));
    }

    return output_array.toHex();
=>     QString output;
    output.setUtf16((ushort*)(X.left().data(16)), 16 / 2); // ushort — 2 char
    return output;

0
Robotex - 18 Февраль, 2011 - 03:26

left нельзя использовать без аргумента

0
_KoT_ - 18 Февраль, 2011 - 05:05
Изображение пользователя _KoT_.

Вы правы. Опечатка) output.setUtf16((ushort*)(X.left(16).data()), 16 / 2); // ushort — 2 char

0
Robotex - 18 Февраль, 2011 - 04:13

Переписал на PHP. Все равно не совпадает, но зато хотя бы уже при каждом запуске выдает одинаковый результат.
<?php

    $S
= array(
   
414667, 201, 162, 216, 124,   1615484, 161, 236, 240,   619,
   
98, 167,   5, 243, 192, 199, 115, 140, 152, 14743, 217, 18876, 130, 202,
   
30, 1558760, 253, 212, 22422, 10366, 11124, 13823, 22918,
  
19078, 196, 214, 218, 158, 22273, 160, 251, 245, 142, 18747, 238, 122,
  
169, 104, 121, 14521, 178,   763, 148, 19416, 13711349533,
  
128, 12793, 15490, 14450395362, 204, 231, 191, 247, 151,   3,
  
2552548, 17972, 165, 181, 209, 21594, 14642, 17286, 170, 198,
   
79, 18456, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116,   4, 241,
   
69, 157, 11289, 100, 113, 13532, 13491, 207, 101, 23045, 168,   2,
   
279637, 173, 174, 176, 185, 246287097, 1055264, 12615,
   
8571, 16335, 22181, 17558, 19592, 249, 206, 186, 197, 23438,
   
448313, 110, 13340, 132,   9, 211, 223, 205, 24465, 1297782,
  
106, 22055, 200, 108, 193, 171, 25036, 225, 123,   812, 189, 17774,
  
120, 136, 149, 139, 22799, 232, 109, 233, 203, 213, 25459,   02957,
  
242, 239, 18314, 10288, 208, 228, 166, 119, 114, 248, 235, 1177510,
   
496880, 180, 143, 2373126, 219, 153, 14151, 15917, 13120);
   
   
$input_string = "";
    echo
"Input string: ".$input_string."<br />";

   
$input_array = array();

    for(
$i=0;$i<strlen($input_string);$i++)
    {
     
$input_array[$i] = $input_string[$i];
    }
   
   
$length = count($input_array);
    echo
"String length: ".$length."<br />";
   
   
$pad = 16 - $length%16;
    echo
"Padding by ".$pad." symbols<br />";
   
    for(
$i=$length;$i<$length+$pad;$i++)
    {
     
$input_array[$i] = $pad;
    }
   
   
$length += $pad;
   
    echo
"Now input_array are:<br /><pre>";
 
var_dump($input_array);
  echo
"</pre>";
  echo
"New length: ".$length."<br />";
   
   
$C = array();
   
    for(
$i=0;$i<16;$i++)
    {
     
$C[$i] = 0;
    }
     
   
$L = 0;
   
    for(
$i = 0;$i<$length/16;$i++)
  {
    for(
$j = 0;$j<16;$j++)
    {
     
$c = $input_array[$i*16+$j];
     
$C[$j] = $C[$j] ^ $S[$c ^ $L];
     
$L = $C[$j];
    }
  }
 
  echo
"Array C:<br /><pre>";
 
var_dump($C);
  echo
"</pre>";
 
  for(
$i=0;$i<count($C);$i++)
    {
     
$input_array[$length+$i] = $C[$i];
    }
   
   
$length += count($C);
 
  echo
"Now input_array are:<br /><pre>";
 
var_dump($input_array);
  echo
"</pre>";
  echo
"New length: ".$length."<br />";
 
 
$X = array();
 
  for(
$i=0;$i<48;$i++)
  {
   
$X[$i] = 0;
  }
 
  for(
$i = 0;$i<$length/16;$i++)
  {
    for(
$j = 0;$j<16;$j++)
    {
     
$X[16+j] = $input_array[$i*16+$j];
     
$X[32+j] = ($X[16+j] ^ $X[j]);
    }

   
$t = 0;

    for(
$j = 0;$j<18;$j++)
    {
      for(
$k = 0;$k<48;$k++)
      {
       
$t = ($X[$k] ^ $S[$t]);
       
$X[$k] = ($X[$k] ^ $S[$t]);
      }

     
$t = ($t+$j)%256;
    }
  }
   
  echo
"Array X:<br /><pre>";
 
var_dump($X);
  echo
"</pre>";
 
 
$result = "";
 
  for(
$i=0;$i<16;$i++)
  {
   
$result .= dechex($X[$i]);
  }
 
  echo
"MD2 Hash: ".$result."<br />";
   
?>

Отправить комментарий

CAPTCHA на основе изображений
Введите цифры