перевод код с vc++ на c#
От: alex2a  
Дата: 29.03.08 13:16
Оценка:
Диар ол..
у меня есть чудовищный код, доставшийся мне от индусов, который должен считать crc16. у меня есть класс, считающий crc и когда я увидел *это*, я заплакал..
я мало знаком с темплэйтами и прочим в vc++, поэтому я не понимаю совершенно как работает этот код.. помогите, пожалуйста разобраться:

WORD CBZXMessage::GetCRC(const CString &sFName, WORD nSerial,long newparameter)
{
    USES_CONVERSION;
 union 
    {
        WORD uWholeWord;
        struct 
        {
            BYTE Low;
            BYTE High;
        }
        ucByte;
    }
    uCRC;
 deque<BYTE> byteQ;
 BYTE bByte;
 bool bRetVal = false;
 WORD nFileCRC = 0;
    uCRC.uWholeWord = nSerial;
 ifstream ifs;
 ifs.open(T2CA(sFName), ios_base::binary );
 while ( ios::goodbit == ifs.rdstate())
 {
  char c;
  ifs.get(  c);
  bByte = c;
  byteQ.push_back( bByte);
  if( byteQ.size() > newparameter) // 7 == magic number ( last char in file is read twice cos ios::eofbit
        //        is only set when a read fails + 4 for CRC + 0x0d + 0x0a)
  {
   uCRC.ucByte.Low ^= byteQ.front();
   byteQ.pop_front();
   for ( int j = 0; j < 8; j++)                 /* do 8 times */
   {
    WORD uFlag = uCRC.uWholeWord & 1;        /* shift seed one bit to right */
    uCRC.uWholeWord = uCRC.uWholeWord >> 1;
    if (uFlag)                          /* if a 1 bit was shifted out */
    {
     uCRC.uWholeWord ^= 0xA001;      /* exclusive or A001 to seed */
    }
   }
  }
 }
 ifs.close();
 return uCRC.uWholeWord;
}

newparameter = 7 всегда, nSerial = 0
где используются прочитаные из файла байты? для чего нужны ксоры ucByte.Low, если идет анализ только uWholeWord?.. Check для этой функции: BA04.

Please HELP!!!

29.03.08 21:46: Перенесено модератором из '.NET' — AndrewVK
Re: перевод код с vc++ на c#
От: nzeemin Россия http://nzeemin.livejournal.com/
Дата: 29.03.08 15:10
Оценка:
Здравствуйте, alex2a, Вы писали:

A>у меня есть чудовищный код, доставшийся мне от индусов, который должен считать crc16. у меня есть класс, считающий crc и когда я увидел *это*, я заплакал..


Не проще ли взять в Гугле "C# crc16", выбрать пример получше и поставить вместо этого?..
Re[2]: перевод код с vc++ на c#
От: alex2a  
Дата: 29.03.08 15:42
Оценка:
Здравствуйте, nzeemin, Вы писали:

N>Не проще ли взять в Гугле "C# crc16", выбрать пример получше и поставить вместо этого?..

у меня есть уже класс, который считает Crc16 по всем правилам — можно задать полином, начальное значение, инверсию и тд, и тп..

но тот код, который я привел мне обязательно нужно перевести на C#, потому что 1) этот код считает CRC по индусскому специальному алгоритму какому-то и 2) удаленная система присылает файл и CRC, а моя система должна подсчитать CRC по тому же алгоритму и смэтчить.. на той стороне есссно, никто давно не знает как это работает и менять ничего не будет, и никаких тебе md5 и тп..
Re: перевод код с vc++ на c#
От: Xander Zerge Россия www.zerge.com
Дата: 29.03.08 22:51
Оценка:
Здравствуйте, alex2a, Вы писали:

A>у меня есть чудовищный код, доставшийся мне от индусов, который должен считать crc16. у меня есть класс, считающий crc и когда я увидел *это*, я заплакал..

A>я мало знаком с темплэйтами и прочим в vc++, поэтому я не понимаю совершенно как работает этот код.. помогите, пожалуйста разобраться

При чём тут темплейты?

1. Последние шесть байт из потока (четырехбайтовая CRC и два байта на конец строки) в подсчёте CRC не учавствуют. Для этого организовано игрище с декой (которое можно заменить чем-нибудь более шустрым). Семь — потому что последний байт только на втором чтении вынесет ifs.rdstate().

2. Каждый байт ксорится с младшим байтом CRC.

3. CRC сдвигается вправо восемь раз — по разу на бит. Каждый сдвиг, когда вправо вылетает единичка, всё слово ксорится с 0xA001.

4. Всё.

Вроде ничего сложного, "индускоссти" немного, разве что вот этот замухрон с union-ом двух байтов в слово. Без него можно (и нужно) обойтись. А так нормально, и даже понятно комментировано. Всякий хлам, типа nFileCRC и bRetVal тоже нужно выкинуть.
... << RSDN@Home 1.2.0 alpha 2 rev. 841>>
Серёжа Новиков,
программист
Re[2]: перевод код с vc++ на c#
От: Sni4ok  
Дата: 30.03.08 00:36
Оценка:
Здравствуйте, Xander Zerge, Вы писали:

XZ>При чём тут темплейты?


там дек юзается)
Re[2]: перевод код с vc++ на c#
От: alex2a  
Дата: 30.03.08 09:19
Оценка:
Здравствуйте, Xander Zerge, Вы писали:

XZ>При чём тут темплейты?

deque вроде темплэйт? просто я не пользовался никогда

XZ>1. Последние шесть байт из потока (четырехбайтовая CRC и два байта на конец строки) в подсчёте CRC не учавствуют. Для этого организовано игрище с декой (которое можно заменить чем-нибудь более шустрым). Семь — потому что последний байт только на втором чтении вынесет ifs.rdstate().

попробую поиграться

XZ>2. Каждый байт ксорится с младшим байтом CRC.

хм.. а где? я вижу uCRC.ucByte.Low ^= byteQ.front(); — но это ведь, насколько я понимаю, ксор первого байта дека с младшим байтом crc?
а в цикле вообще byteQ не участвует..

XZ>Вроде ничего сложного, "индускоссти" немного, разве что вот этот замухрон с union-ом двух байтов в слово. Без него можно (и нужно) обойтись. А так нормально, и даже понятно комментировано. Всякий хлам, типа nFileCRC и bRetVal тоже нужно выкинуть.

вам, профессионалам от c++ легко
Re[3]: перевод код с vc++ на c#
От: Xander Zerge Россия www.zerge.com
Дата: 30.03.08 09:27
Оценка:
Здравствуйте, Sni4ok, Вы писали:

XZ>>При чём тут темплейты?

S>там дек юзается)
Так юзается, не описывается же. std::string тогда тоже темплейт.
... << RSDN@Home 1.2.0 alpha 2 rev. 841>>
Серёжа Новиков,
программист
Re: перевод код с vc++ на c#
От: alex2a  
Дата: 30.03.08 12:11
Оценка:
Спасибо Xander Zerge, с кодом я разобрался.
если кому интересно, реализация в C# следущая:
public ushort MercuryCRC(string strFileName)
{
ushort crc = 0x0000;
System.IO.FileInfo fi = new FileInfo(strFileName);

const int BlockSize = 1024; // block size for file read
int numberOfFullBlocks = (int)((fi.Length — 6) / BlockSize);
/* number of blocks of 256 to read
* 6 is magic hindu number.
* we skip last 6 bytes in file
* */

// bytes rest after all 256 blocks are read
int AuxBlockSize = (numberOfFullBlocks == 0) ? (int)(fi.Length — 6) : (int)((fi.Length — 6) % BlockSize);

BinaryReader bn = new BinaryReader(File.Open(strFileName, FileMode.Open), System.Text.Encoding.Default);
byte[] buf = new byte[BlockSize];

try
{
for (int i = 0; i < numberOfFullBlocks; i++)
{
buf = bn.ReadBytes(BlockSize);
foreach (byte by in buf)
{
crc ^= (ushort)by;
for (int j = 0; j < 8; j++)
{
bool flag = Convert.ToBoolean(crc & 1); // test high word of crc and 1
crc >>= 1;
if (flag)
crc ^= 0xa001;
}// for 8 times
}// foreach by in buf
}// for number of full blocks

// now read rest bytes
buf = bn.ReadBytes(AuxBlockSize); // read number of the rest bytes
foreach (byte by in buf) // for each
{
crc ^= (ushort)by;
for (int j = 0; j < 8; j++)
{
bool flag = Convert.ToBoolean(crc & 1); // test high word of crc and 1
crc >>= 1;
if (flag)
crc ^= 0xa001;
}// for 8 times
}// foreach of the rest bytes
return crc;
}//try
catch (Exception ex)
{
throw new Exception("Error calculation M-CRC for " + strFileName + "\n" + ex.Message);
return 0;
}
finally
{
bn.Close();
}
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.