Re: CRC32 - Не выходит каменный цветок
От: Maniacal Россия  
Дата: 17.10.19 07:59
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Здравствуйте!


У>Накопал в инетах код для CRC8 и CRC16. Для CRC32 никак не найти бестабличный вариант. Посмотрел на CRC8 и CRC16 — они практически идентичны. Написал универсальную функцию. Она отрабатывает для CRC8 и CRC16 нормально, для CRC32 никак не могу получить то, что вроде бы должно получится.


У>Прогонял на таких данных:

У>
  Скрытый текст

У> // Name : CRC-8
У> // Poly : 0x31 x^8 + x^5 0+ x^4 + 1
У> // Init : 0xFF
У> // Revert: false
У> // XorOut: 0x00
У> // Check : 0xF7 ("123456789")
У> // MaxLen: 15 байт(127 бит) — обнаружение одинарных, двойных, тройных и всех нечетных ошибок

У> // Name : CRC-16 CCITT
У> // Poly : 0x1021 x^16 + x^12 + x^5 + 1
У> // Init : 0xFFFF
У> // Revert: false
У> // XorOut: 0x0000
У> // Check : 0x29B1 ("123456789")
У> // MaxLen: 4095 байт (32767 бит) — обнаружение одинарных, двойных, тройных и всех нечетных ошибок

У> // Name : CRC-32
У> // Poly : 0x04C11DB7 x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11
У> // + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
У> // Init : 0xFFFFFFFF
У> // Revert: true
У> // XorOut: 0xFFFFFFFF
У> // Check : 0xCBF43926 ("123456789")
У> // MaxLen: 268 435 455 байт (2 147 483 647 бит) — обнаружение одинарных, двойных, пакетных и всех нечетных ошибок


У>Для CRC32 и реверсировал, и реципрокалил полином — в итоге всё равно фигня получается
У>
  crc.h
У>#include <stdint.h>

У>template<typename BitsType>
У>BitsType makeMask( )
У>{
У>    return ~(BitsType)0;
У>}

У>template<typename BitsType>
У>inline
У>BitsType makeMostSignificantBit( )
У>{
У>    const BitsType mask = makeMask<BitsType>();
У>    return mask - (mask>>1); //MSBit;
У>}


У>uint8_t revertBits( uint8_t u )
У>{
У>    // 0x00 (0000)  -> 0x00 (0000)
У>    // 0x01 (0001)  -> 0x08 (1000)
У>    // 0x02 (0010)  -> 0x04 (0100)
У>    // 0x03 (0011)  -> 0x0C (1100)
У>    // 0x04 (0100)  -> 0x02 (0010)
У>    // 0x05 (0101)  -> 0x0A (1010)
У>    // 0x06 (0110)  -> 0x06 (0110)
У>    // 0x07 (0111)  -> 0x0E (1110)
У>    // 0x08 (1000)  -> 0x01 (0001)
У>    // 0x09 (1001)  -> 0x09 (1001)
У>    // 0x0A (1010)  -> 0x05 (0101)
У>    // 0x0B (1011)  -> 0x0D (1101)
У>    // 0x0C (1100)  -> 0x03 (0011)
У>    // 0x0D (1101)  -> 0x0B (1011)
У>    // 0x0E (1110)  -> 0x07 (0111)
У>    // 0x0F (1111)  -> 0x0F (1111)
У>    static uint8_t revertTable[16] = { 0x00, 0x08, 0x04, 0x0C
У>                                     , 0x02, 0x0A, 0x06, 0x0E
У>                                     , 0x01, 0x09, 0x05, 0x0D
У>                                     , 0x03, 0x0B, 0x07, 0x0F
У>                                     };
У>    return  revertTable[ (u&0xF0)>>4 ]
У>         | (revertTable[ (u&0x0F) ] << 4)
У>         ;
У>}

У>uint16_t revertBits( uint16_t u )
У>{
У>    return  (uint16_t)revertBits( (uint8_t)(u>>8  ) )
У>         | ((uint16_t)revertBits( (uint8_t)(u&0xFF) )<<8)
У>         ;
У>}

У>uint32_t revertBits( uint32_t u )
У>{
У>    return  (uint32_t)revertBits( (uint16_t)(u>>16  ) )
У>         | ((uint32_t)revertBits( (uint16_t)(u&0xFFFF) )<<16)
У>         ;
У>}

У>template<typename BitsType>
У>BitsType revertBits( BitsType bits, bool revert )
У>{
У>    return revert ? revertBits(bits) : bits;
У>}


У>// https://en.wikipedia.org/wiki/Mathematics_of_cyclic_redundancy_checks#Reversed_representations_and_reciprocal_polynomials

У>//   1 [0  0  0  1 |0  0  0  0 |0  0  1  0 |0  0  0  1]  Normal
У>//  [1  0  0  0 |0  1  0  0 |0  0  0  0 |1  0  0  0] 1   Reverse
У>//   1 [0  0  0  0 |1  0  0  0 |0  0  0  1 |0  0  0  1]  Reciprocal
У>//

У>// Reciprocal - подразымевающаяся в N+1 разряде единица всасывается сдвигом право, 
У>// затем это число реверсируется

У>template<typename BitsType>
У>BitsType reciprocalBits( BitsType bits, bool revert )
У>{
У>    //if (!reciprocal) return bits;
У>    //BitsType mask = ~(CrcType)0;
У>    BitsType msb = makeMostSignificantBit<BitsType>();
У>    BitsType res = (bits>>1)|msb;
У>    return revert ? res : revertBits<BitsType>( res, true);
У>}


У>enum class CrcTransformType
У>{
У>    normal,
У>    reversed,
У>    reciprocal,
У>    reversed_reciprocal
У>};


У>template<typename BitsType>
У>BitsType crcPrepareValue( BitsType bits, CrcTransformType trt )
У>{
У>    switch(trt)
У>    {
У>        case CrcTransformType::reversed:
У>             return revertBits(bits);
У>        case CrcTransformType::reciprocal:
У>             return reciprocalBits(bits, false);
У>        case CrcTransformType::reversed_reciprocal:
У>             return reciprocalBits(bits, false);
У>        default:
У>             return bits;
У>    }
У>}



У>template<typename UintType>
У>UintType uintUnaryMinus( UintType u )
У>{
У>    return -u;
У>}

У>template<>
У>inline
У>uint8_t uintUnaryMinus<uint8_t>(uint8_t u)
У>{
У>    return (uint8_t)(-((int8_t)u));
У>}

У>template<>
У>inline
У>uint16_t uintUnaryMinus<uint16_t>(uint16_t u)
У>{
У>    return (uint16_t)(-((int16_t)u));
У>}

У>template<>
У>inline
У>uint32_t uintUnaryMinus<uint32_t>(uint32_t u)
У>{
У>    return (uint32_t)(-((int32_t)u));
У>}





У>// Check : 0xF7 ("123456789")
У>// Check : 0x29B1 ("123456789")
У>// Check : 0xCBF43926 ("123456789")

У>template< typename CrcType, CrcType NBits, CrcType Poly, bool revert >
У>CrcType crcStepImpl( CrcType crc, uint8_t byte )
У>{
У>#if 1

У>    const CrcType nshift = NBits - 8; //NBits>16 ? 16 : NBits - 8; //NBits - 8; //NShift;
У>    const CrcType mask   = makeMask<CrcType>();
У>    const CrcType msbit = makeMostSignificantBit<CrcType>();
У>    const CrcType poly   = Poly;

У>    if (nshift)
У>        crc ^= ((CrcType)byte);// << nshift;
У>    else
У>        crc ^= ((CrcType)byte); // << NShift;
 
У>    for ( auto i = 0u; i != 8u; ++i)
У>    {
У>        //crc = crc & 1 ? (crc >> 1) ^ poly : crc >> 1;
У>        crc = crc & msbit ? (crc << 1) ^ poly : crc << 1;
У>        crc &= mask;

У>        //crc = (crc >> 1) ^ (- (CrcType)(crc & 1) & poly);
У>        //crc = (crc >> 1) ^ (uintUnaryMinus<CrcType>(crc & 1) & poly);
У>        //crc = (crc << 1) ^ (uintUnaryMinus<CrcType>(crc & msbit) & poly);
        
У>    }

У>#else

У>    if (NShift)
У>        crc ^= ((CrcType)byte) << NShift;
У>    else
У>        crc ^= ((CrcType)byte); // << NShift;
 
У>    for ( auto i = 0u; i != 8u; ++i)
У>    {
У>        crc = crc & MSBit ? (crc << 1) ^ Poly : crc << 1;
У>    }

У>#endif

У>    return crc;
У>}

У>//template< typename CrcType, CrcType MSBit, CrcType NShift, CrcType Poly, CrcType Init >
У>template< typename CrcType, CrcType NBits, CrcType Poly, bool revert, CrcType XorOut, CrcType Init >
У>CrcType crcImpl( const uint8_t *pBuf, size_t len )
У>{
У>    CrcType crc = Init;
У>    while(len--)
У>    {
У>        crc = crcStepImpl< CrcType, NBits, Poly, revert >( crc, *pBuf++ );
У>    }

У>    return crc ^ XorOut;
У>    //return revertBits(crc, revert) ^ XorOut;
У>    //return revertBits( (CrcType)(crc ^ XorOut), revert) ;
У>}


У>template< uint8_t Poly    = 0x31u
У>        , bool    revert  = false
У>        , uint8_t XorOut  = 0x00u
У>        , uint8_t Init    = 0xFFu
        >>
У>uint8_t crc8( const uint8_t *pBuf, size_t len )
У>{
У>    return crcImpl< uint8_t, 8u, Poly, revert, XorOut, Init >( pBuf, len );
У>}

У>template< uint16_t Poly   = 0x1021u
У>        , bool     revert = false
У>        , uint16_t XorOut = 0x0000u
У>        , uint16_t Init   = 0xFFFFu
        >>
У>uint16_t crc16( const uint8_t *pBuf, size_t len )
У>{
У>    return crcImpl< uint16_t, 16u, Poly, revert, XorOut, Init >( pBuf, len );
У>}

У>template< uint32_t Poly   = 0x04C11DB7u
У>        , bool     revert = true
У>        , uint32_t XorOut = 0xFFFFFFFFu
У>        , uint32_t Init   = 0xFFFFFFFFu
        >>
У>uint32_t crc32( const uint8_t *pBuf, size_t len )
У>{
У>    return crcImpl< uint32_t, 32u, Poly, revert, XorOut, Init >( pBuf, len );
У>}
У>
  main.cpp
#include <iostream>
У>#include <iomanip>

У>#include "../../crc.h"


У>// Check : 0xF7 ("123456789")
У>// Check : 0x29B1 ("123456789")
У>// Check : 0xCBF43926 ("123456789")

У>using std::cout;
У>using std::endl;

У>int main(int argc, char* argv[])
У>{
У>    const char data[10] = "123456789";
У>    size_t sz = 9;

У>    // http://users.ece.cmu.edu/~koopman/crc/crc32.html
У>    uint16_t  bits16  = 0x1021;
У>    uint16_t  rvrt16  = revertBits( bits16, true );
У>    uint16_t  rcprD16 = reciprocalBits( bits16, false );
У>    uint16_t  rcprR16 = reciprocalBits( bits16, true );
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<bits16 <<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rvrt16 <<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rcprD16<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rcprR16<<endl;
У>    cout<<"---"<<endl;

У>    // (0x82608edb; 0x104c11db7) <=> (0xedb88320; 0x1db710641) {4294967263,91607,2974,268,171,91,57,34,21,12,10,10,10} | gold | (*p) IEEE 802.3; CRC-32
У>    //   Normal     Reversed   Reciprocal  Reversed reciprocal
У>    // 0x04c11db7  0xedb88320  0xdb710641  0x82608edb
У>    // 0x82608edb  0xdb710641  0xb6e20c83  0xc130476d

У>    uint32_t  bits32  = 0x04c11db7;
У>    uint32_t  rvrt32  = revertBits( bits32, true );
У>    uint32_t  rcprD32 = reciprocalBits( bits32, false );
У>    uint32_t  rcprR32 = reciprocalBits( bits32, true );
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<bits32 <<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rvrt32 <<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rcprD32<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rcprR32<<endl;
У>    cout<<"---"<<endl;

У>              bits32  = 0x82608edb;
У>              rvrt32  = revertBits( bits32, true );
У>              rcprD32 = reciprocalBits( bits32, false );
У>              rcprR32 = reciprocalBits( bits32, true );
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<bits32 <<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rvrt32 <<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rcprD32<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rcprR32<<endl;
У>    cout<<"---"<<endl;

У>              bits32  = 0x82608edb;
У>              rvrt32  = revertBits( bits32, true );
У>              rcprD32 = reciprocalBits( bits32, false );
У>              rcprR32 = reciprocalBits( bits32, true );
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<bits32 <<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rvrt32 <<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rcprD32<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<rcprR32<<endl;
У>    cout<<"---"<<endl;



У>    unsigned crc_8    = (unsigned)crc8 ( (const uint8_t*)data, sz );
У>    unsigned crc_16   = (unsigned)crc16( (const uint8_t*)data, sz );
У>    unsigned crc_32_1 = (unsigned)crc32( (const uint8_t*)data, sz );
У>    unsigned crc_32_2 = (unsigned)crc32<0x04c11db7u>( (const uint8_t*)data, sz );
У>    unsigned crc_32_3 = (unsigned)crc32<0xedb88320u>( (const uint8_t*)data, sz );
У>    unsigned crc_32_4 = (unsigned)crc32<0xdb710641u>( (const uint8_t*)data, sz );
У>    unsigned crc_32_5 = (unsigned)crc32<0x82608edbu>( (const uint8_t*)data, sz );
У>    unsigned crc_32_6 = (unsigned)crc32<0xb6e20c83>( (const uint8_t*)data, sz );
У>    unsigned crc_32_7 = (unsigned)crc32<0xc130476d>( (const uint8_t*)data, sz );
У>    //unsigned crc32_8 = (unsigned)crc32<>( (const uint8_t*)data, sz );


У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<crc_8 <<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<crc_16<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<crc_32_1<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<crc_32_2<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<crc_32_3<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<crc_32_4<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<crc_32_5<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<crc_32_6<<endl;
У>    cout<<std::hex<<std::setw(8)<<std::right<<std::setfill('0')<<crc_32_7<<endl;
У>    //    <<crc8 <<std::endl
У>    //    <<crc16<<std::endl
У>    //    <<crc32<<std::endl;
У>    return 0;
У>}
У>

У>Что-то никак не дотумкать, почему оно не работает и где чего еще покрутить можно


Тут не оно?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.