:: Visual Foxpro, Foxpro for DOS
Sys(2007 и странный CRC32
StasKryzh

Сообщений: 14
Дата регистрации: 26.09.2009
Разрабатываю интерфейс для работы со сторонним АПИ (ПРРО Украина).
Для определенных функций они требуют передачи контрольной суммы строки.
У них в документации приведен пример вычисления CRC32:
cHashStr = "179625192271939,20082020,142338,10,4000002411,10,cdd68bb111f8993f3603f0179341571b35b73a07d5acee9b28fbfb714698e1b3"
nCRC32: HEX = 0xbddbbda6, UInt = 3185294758

Пытаюсь на Фоксе получить crc32:
nCRC32 = Val(Sys(2007, cHashStr, 0, 1))
Получаю:
nCRC32: HEX = 0xA6BDDBBD, UInt = 2797460413

Пытаюсь использовать winAPI:
Declare Integer RtlComputeCrc32 in ntdll.dll Integer, String, integer
nCRC32 = RtlComputeCrc32(0, cHashStr, Len(cHashStr))
Получаю:
Int = -1497506883
Перевожу в UInt (+2^32), и получаю тоже, что вернул Фокс:
HEX = 0xA6BDDBBD, UInt = 2797460413

Видно, что в получаемые результаты - в HEX это зеркальное отображение того что в документации.

Делаю переворот: (Int = -1497506883)
nCRC32 = CToBin(BinToC(nCRC32, '4S'), '4RS')
Перевожу в UInt, получаю результат - такой, как и в документации - nCRC32: HEX = 0xbddbbda6, UInt = 3185294758.

Текст кода:
cHashStr = "179625192271939,20082020,142338,10,4000002411,10,cdd68bb111f8993f3603f0179341571b35b73a07d5acee9b28fbfb714698e1b3"
nCRC32 = Val(Sys(2007, cHashStr, 0, 1))
If nCRC32 > 2^31 && получили Uint
nCRC32 = nCRC32 - 2^32 && -> INT, так как переворот возможен только для INT
EndIf
nCRC32 = CToBin(BinToC(nCRC32, '4S'), '4RS') && переворот
If nCRC32 < 0
nCRC32 = nCRC32 + 2^32 && -> UINT
EndIf
? Transform(nCRC32, '@0')

ВОПРОС:
Я понимаю, что это подгонка под ответ, но другого решения я не нашел... Вот и хочется узнать Ваше мнение - всегда ли этот решение будет давать правильный результат? Или может все намного банальнее, и есть намного более простое решение?
Ratings: 0 negative/0 positive
Re: Sys(2007 и странный CRC32
sphinx

Сообщений: 31189
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
StasKryzh
Для определенных функций они требуют передачи контрольной суммы строки.

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


------------------
"Veni, vidi, vici!"(с)




Исправлено 1 раз(а). Последнее : sphinx, 28.11.20 22:29
Ratings: 0 negative/0 positive
Re: Sys(2007 и странный CRC32
StasKryzh

Сообщений: 14
Дата регистрации: 26.09.2009
Увы, но обратная связь с разработчиками ПО для Налоговой - это не для простых смертных... Спасибо им и за пример предоставленный в документации. И если бы не зеркальность результатов - то можно было бы подумать, что у меня и у них CRC32 имеют совершенно разные смыслы... Тогда бы и пытался связаться и уточнять у них...
Ratings: 0 negative/0 positive
Re: Sys(2007 и странный CRC32
sphinx

Сообщений: 31189
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Пишите в ЛС. Все, что по теме, как есть и как надо, какие требования. Свои примеры. Часть переписки. Если секретно и не для всех. Данные можно порезать, но 2-3 строки надо.
Если НЕ секретно - сюда выкладывайте, люди отзывчивые здесь.


------------------
"Veni, vidi, vici!"(с)
Ratings: 2 negative/0 positive
Re: Sys(2007 и странный CRC32
_vit

Сообщений: 5176
Дата регистрации: 29.07.2002
В цифровых системах используется два вида последовательностей байтов Big endian и Little endian.

Little endian используется в интеловских процессорах.
Какие то системы могут использовать обратный порядок.


Цитата:
соглашение little-endian поддерживают меньше кросс-платформенных протоколов и форматов данных, чем big-endian.

en.wikipedia.org

Так что не удивительно.



Исправлено 1 раз(а). Последнее : _vit, 28.11.20 23:24
Ratings: 0 negative/0 positive
Re: Sys(2007 и странный CRC32
StasKryzh

Сообщений: 14
Дата регистрации: 26.09.2009
sphinx
Пишите в ЛС. Все, что по теме, как есть и как надо, какие требования. Свои примеры. Часть переписки. Если секретно и не для всех. Данные можно порезать, но 2-3 строки надо.
Если НЕ секретно - сюда выкладывайте, люди отзывчивые здесь.

Вы меня неправильно поняли... Я имел ввиду - контактов для обратной связи просто нету...
Ratings: 0 negative/0 positive
Re: Sys(2007 и странный CRC32
StasKryzh

Сообщений: 14
Дата регистрации: 26.09.2009
_vit
В цифровых системах используется два вида последовательностей байтов Big endian и Little endian.
Цитата:
соглашение little-endian поддерживают меньше кросс-платформенных протоколов и форматов данных, чем big-endian.

en.wikipedia.org

Так что не удивительно.

Спасибо! Идея понятна. Получается я уже реализовал преобразование между BE и LE ))) Остается надеяться что правильно ))
Ratings: 0 negative/0 positive
Re: Sys(2007 и странный CRC32
vasilenko_timur91
Автор

Сообщений: 1
Дата регистрации: 18.12.2020
Здравствуйте.
Тоже занимаюсь этим вопросом (ПРРО), только на PHP.
Ваша идея с обращением шестнацатеричного числа у меня тоже заработала, спасибо за наводку.

Мне прислали из поддержки налоговой их алгоритм расчёта CRC32 - вставлю его тут, может кому-то чем-то поможет.
Ответ на контрольный пример в коде

Часть текста скрыта
using System;
using System.Text;
using System.Collections.Generic;
using System.Security.Cryptography;
public class Program
{
public static void Main()
{
var ControlNumberSource = "613471366090123,17122020,142324,489,4000032793,1";
var sequence = Encoding.ASCII.GetBytes( ControlNumberSource );
using( var crc32 = new Crc32() ) {
crc32.Initialize();
crc32.ComputeHash( sequence );
var calculatedCrc32 = BitConverter.ToUInt32( crc32.Hash, 0 );
var ControlNumber = (int)(calculatedCrc32 % 1000);
if( ControlNumber == 0 ) {
ControlNumber = 1;
}
Console.WriteLine($"calculatedCrc32: {calculatedCrc32}, ControlNumber: {ControlNumber}");
// calculatedCrc32: 2147742393, ControlNumber: 393
}
}
}
public sealed class Crc32 : HashAlgorithm {
public const uint DefaultPolynomial = 0xedb88320u;
public const uint DefaultSeed = 0xffffffffu;
private static uint[] _defaultTable;
private readonly uint _seed;
private readonly uint[] _table;
private uint _hash;
public Crc32()
: this( DefaultPolynomial, DefaultSeed ) {
}
public Crc32( uint polynomial, uint seed ) {
_table = InitializeTable( polynomial );
_seed = _hash = seed;
}
public override int HashSize => 32;
public override void Initialize() {
_hash = _seed;
}
protected override void HashCore( byte[] array, int ibStart, int cbSize ) {
_hash = CalculateHash( _table, _hash, array, ibStart, cbSize );
}
protected override byte[] HashFinal() {
var hashBuffer = UInt32ToBigEndianBytes( ~_hash );
HashValue = hashBuffer;
return hashBuffer;
}
public static uint Compute( byte[] buffer ) {
return Compute( DefaultSeed, buffer );
}
public static uint Compute( uint seed, byte[] buffer ) {
return Compute( DefaultPolynomial, seed, buffer );
}
public static uint Compute( uint polynomial, uint seed, byte[] buffer ) {
return ~CalculateHash( InitializeTable( polynomial ), seed, buffer, 0, buffer.Length );
}
private static uint[] InitializeTable( uint polynomial ) {
if( polynomial == DefaultPolynomial && _defaultTable != null ) {
return _defaultTable;
}
var createTable = new uint[256];
for( var i = 0; i < 256; i++ ) {
var entry = (uint)i;
for( var j = 0; j < 8; j++ ) {
if( (entry & 1) == 1 ) {
entry = (entry >> 1) ^ polynomial;
}
else {
entry = entry >> 1;
}
}
createTable = entry;
}
if( polynomial == DefaultPolynomial ) {
_defaultTable = createTable;
}
return createTable;
}
private static uint CalculateHash( uint[] table, uint seed, IList<byte> buffer, int start, int size ) {
var hash = seed;
for( var i = start; i < size + start; i++ ) {
unchecked {
hash = (hash >> 8) ^ table[buffer[i] ^ (hash & 0xff)];
}
}
return hash;
}
private static byte[] UInt32ToBigEndianBytes( uint uint32 ) {
var result = BitConverter.GetBytes( uint32 );
if( BitConverter.IsLittleEndian ) {
Array.Reverse( result );
}
return result;
}
}




[i]Исправлено 2 раз(а). Последнее : vasilenko_timur91, 18.12.20 15:19
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 59 PaulWist Victoriacom  (Гостей: 57)

© 2000-2024 Fox Club 
Яндекс.Метрика