Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Подсчёт CRC32B


Автор: DarkProg 2.4.2012, 09:30
В общем понимаю, что наверное вопрос не совсем в эту ветку, но в принципе в эту наверное, т.к. пишу на делфи...

У меня стоит задача подсчитать контрольную сумму строки алгоритмом CRC32B.

Я нашёл HashLib в которой заявлена поддержка указанного алгоритма, но!, внимание - результат неверен!
С чего решил - да очень просто, люди которым делаю чейчас считают его каким-то кривым образом, используя для этого веб-сервис, при этом результат верен у них, потому что проходится проверка(реализуется проверка не заказчиками, а третьей стороной, куда и отправляется строка с контрольной суммой).

Внимание вопрос: может кто знает уже нормальный готовый алгоритм CRC32B или ткнёт меня носом в понятное описание алгоритма?

P.S. у меня задача реализовать это всё на делфе.
P.P.S. для одного символа я научился считать(меняется одна строчка в исходниках HashLib), а вот для двух и более символов алгоритм вообще не работает(экспериментировал пока только с английскими символами, потому что их контрольная сумма не зависит от кодировки)

Автор: Ne1tr1n0 2.4.2012, 10:19
А что за веб-сервис проверяет чексумму? Может самому использовать его для проверки?
Вот исходник на асме, попробуй, правильно он считает или нет? Быть может сделать объектник или либу на асме и прилинковать её статически к проекту на дельфи?
http://tuts4you.com/download.php?view.550
Вот ещё исходник на сях, http://read.pudn.com/downloads91/sourcecode/windows/system/346817/CRC32b%20by%20Mark%20Nelson.c__.htm
Ещё вроде как краем уха слышал, что тотал коммандер может считать CRC-32b.

Автор: ksili 2.4.2012, 10:55
Проблема я так понимаю не в том, что человек не может запрограммировать или проверить. А в том, что нет описания того, что надо запрограммировать. По-моему единственный вариант сохранить свое время и нервы - это запросить описание того, что им надо считать, и сделать. 

Про CRC есть описание в книге Вернер "Основвы кодирования". Правда кратко в конце главы про циклическое кодирование. Поэтому чтобы все понять, тебе надо будет прочитать всю эту главу. За день это сделать реально. Там же приводится порождающий многочлен для CRC-32. А вот что такое CRC-32B я не в курсе. В книге об этом ничего нет.

Автор: Qu1nt 2.4.2012, 11:11
http://www.hackersdelight.org/HDcode/newCode/crc.c.txt

Автор: DarkProg 2.4.2012, 19:11
Конешно спасибо, но гулить я тоже умею, о разновидностях CRC32 пока не сталкнулся с этой проблемой даже особо и не знал и если честно даже заморачиваться бы не стал... 
Веб-сервис, да любой, вот первый пример который я нашёл http://tools.adw0rd.ru/gethash/, а так гугл дал ещё добрый десяток вариантов. Использовать весервис - это извините изврат, у заказчиков 0.75 программиста и поэтому они юзают кривейший способ, а я то мегахадкорный программист, так что трудности мне нипочём smile Главное понять что искать...

Я кажется понял в чём проблема HashLib, она состоит в том что я невнимательно почитал примеры и проблема состоит в том что у меня коды символов которые ожидаются алгоритмом не совпадают с тем которые я алгоритму даю... что за беда, я даже не знаю... Там в примерах и в библиотеках есть простенький самотест на котором всё валится - там задаётся строка и ожидается получение "правильной" контрольной суммы, а у меня считается она неверно, в результате чего примеры не работают, точнее если отключить самотестирование, то всё работает, но к сожалению результат неверен...

Автор: northener 2.4.2012, 19:23
Цитата(DarkProg @  2.4.2012,  19:11 Найти цитируемый пост)
Там в примерах и в библиотеках есть простенький самотест на котором всё валится - там задаётся строка и ожидается получение "правильной" контрольной суммы, а у меня считается она неверно, в результате чего примеры не работают, 

Вы уверены что примеры ждут именно такой тип строки, который вы используете?

Автор: DarkProg 2.4.2012, 19:51
Цитата(northener @  2.4.2012,  20:23 Найти цитируемый пост)
Вы уверены что примеры ждут именно такой тип строки, который вы используете? 

Вот копипаст функции которая используется внутри для самотестирования

Код

    HASH_CRC32B: ret := SingleTest(HashType, 'checksum', '9adf6fde'); 

Т.е. обычные строки, или по другому AnsiString
Я пробовал играться с UTF8, Unicode но эффект один - никакой.

Интересен тот факт что зачем-то разработчики алгоритма выболняют операцию bswap для результата.... хотя если её отключить, то результат который получен при помощи веб-сервиса совпадёт с ожидаемым, но у меня вообще отличный результат и операция bswap тут явно не при чём.

Автор: Qu1nt 2.4.2012, 20:53
DarkProg, там вообще-то есть реализация CRC32B на C.
Путем нехитрого перевода на Delphi получаем:
Код

function Crc32B(const Text: String): Cardinal;
var
  Byte, Mask, I: Cardinal;
begin
  Result := Cardinal(-1);
  for Byte in TEncoding.UTF8.GetBytes(Text) do
  begin
    Result := Result xor Byte;
    for I := 7 downto 0 do
    begin
      Mask := -(Result and 1);
      Result := (Result shr 1) xor (Mask and $EDB88320);
    end;
  end;

  Result := not Result;
end;

Результат такой же как и на http://tools.adw0rd.ru/gethash/.

Автор: DarkProg 2.4.2012, 20:58
Цитата(Qu1nt @  2.4.2012,  21:53 Найти цитируемый пост)
DarkProg, там вообще-то есть реализация CRC32B на C.

Видел, и как раз занимался сейчас её переводом... но спасибо +1 от меня(я битовые операции долго обычно мучаю), за помощь, надеюсь всё будет так как именно надо заказчику.

Автор: DarkProg 8.4.2012, 22:44
Эмм... у меня тут есть небольшая проблема... похоже что считать контрольную сумму надо в WIN1251... и почему-то результат не совпадает... я себе мозг сломал... пробовал в лоб понять что за ерунда(тупой перебор от 0 до 255 и вычисление контрольной суммы), но не получилось что-то

Дополнил выше приведенную функцию вот так

Код

  Win1251:TEncoding;
begin
  ...
  Win1251:=TEncoding.GetEncoding(1251);
  for Byte in Win1251.GetBytes(Text) do
  ...


Судя во результату в Byte, то всё работает верно, но почему-то web-интерфейс даёт абсолютно иное значение, я даже не знаю чему верить....

Автор: ksili 9.4.2012, 06:31
Очевидно же. Надо разобраться откуда веб-интерфейс берёт значение. И если оттуда, то не происходит ли по пути конвертация. Например в base64.

Автор: Qu1nt 9.4.2012, 08:44
Стоп. У меня результаты были идентичные с http://tools.adw0rd.ru/gethash/. О каком веб-интерфейсе речь?

Автор: DarkProg 9.4.2012, 12:25
Цитата(Qu1nt @  9.4.2012,  09:44 Найти цитируемый пост)
Стоп. У меня результаты были идентичные с http://tools.adw0rd.ru/gethash/. О каком веб-интерфейсе речь? 

У меня тоже,  если речь идёт о UTF8, но если WIN-1251, то результаты отличаются как земля и небо...
Зная, что win1251 кодируется одним байтом, то я сделал тупой вариант перебора чисел от 0 до 255, и попытался сравнить с контрольной суммой буквы Б посчитанной в веб интерфейсе, в результате ни одно из посчитанных значений не совпало с тем что предлагает эта веб-страничка.

Автор: ksili 9.4.2012, 13:09
Из названия CRC32 следует, что ему нужно минимум 32 бита - т.е. 4 байта. Один байт - ваша буква. А вот остальные как-то заполняются. Возможно у вас и в алгоритме с сайта они заполняются по-разному.

Автор: DarkProg 9.4.2012, 20:27
Вообще как бы независимо от реализации результат должен быть одним, но видимо не судьба...

Автор: DarkProg 9.4.2012, 20:49
Цитата(ksili @  9.4.2012,  14:09 Найти цитируемый пост)
 А вот остальные как-то заполняются

По идее должно забиваться нулями.

Автор: Qu1nt 9.4.2012, 21:21
ksili, не вводи людей в заблуждение.
DarkProg, скорее всего у него где-то ошибка. Попробуй с ним связаться и попросить исходники.

Автор: DarkProg 9.4.2012, 22:59
Цитата(Qu1nt @  9.4.2012,  22:21 Найти цитируемый пост)
DarkProg, скорее всего у него где-то ошибка.

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

Автор: ksili 10.4.2012, 03:37
Цитата(DarkProg @  10.4.2012,  00:27 Найти цитируемый пост)
независимо от реализации результат должен быть одним

Это если реализуется один и тот же алгоритм.

Автор: ksili 10.4.2012, 09:50
Цитата из википедии:
Цитата

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


Как я и писал сначала - надо узнать конкретно, что надо делать. Тогда будет потрачено меньше времени и сил.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)