メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

# dkcCRC.c

説明を見る。

    00001
    00008 #define DKUTIL_C_CRC_C
    00009 #include "dkcCRC.h"
    00010
    00011 typedef ULONG value_type;
    00012 typedef USHORT value_type16;
    00013
    00014 /*size_t a = (0x00000001 << Bits);
    00015 size_t b = (0xFFFFFFFF >> 32 - Bits);
    00016 size_t result = a & b;
    00017 (0x00000001 << Bits) & (0xFFFFFFFF >> 32 - Bits)
    00018 */
    00019 static DKC_INLINE value_type mask_value( size_t Bits){
    00020     //return (~(0x80000000 >> (Bits )) << 1) + 1;
    00021     //size_t a = (0x00000001 << Bits);
    00022     size_t b = (0xFFFFFFFF >> (32 - Bits));
    00023     //size_t result = a & b;
    00024     return b;
    00025
    00026     //return (0x00000001 << Bits) & (0xFFFFFFFF >> (32 - Bits));
    00027 }
    00028
    00029
    00031 static  unsigned char  index( value_type rem, unsigned char x ,size_t Bits,BOOL DoReflect)
    00032 {
    00033     return (BYTE)(x ^ ( rem >> (DoReflect ? 0u : Bits - CHAR_BIT) ));
    00034 }
    00035
    00037 static  value_type  shift( value_type rem ,BOOL DoReflect)
    00038 {
    00039     return DoReflect ? rem >> CHAR_BIT : rem << CHAR_BIT;
    00040 }
    00041 /*
    00042 static  value_type  shift( value_type rem )
    00043 {
    00044     return rem << CHAR_BIT;
    00045 }
    00046
    00047 static  unsigned char  index( value_type rem, unsigned char x ,size_t Bits)
    00048 {
    00049     return (unsigned char)(x ^ ( rem >> (Bits - CHAR_BIT) ));
    00050 }
    00051 */
    00052 static value_type reflector(size_t Bits,value_type x){
    00053     value_type        reflection = 0;
    00054   value_type const  one = 1;
    00055     size_t i;
    00056
    00057   for ( i = 0 ; i < Bits ; ++i, x >>= 1 )
    00058   {
    00059       if ( x & one )
    00060       {
    00061           reflection |= ( one << (Bits - 1u - i) );
    00062       }
    00063   }
    00064
    00065
    00066   //return reflection;
    00067     //return reflection & (~(0x80000000 >> (Bits )) << 1) + 1;
    00068
    00069     return reflection & mask_value(Bits);
    00070 }
    00071
    00072 static value_type reflection(BOOL DoReflect,size_t Bits,value_type x){
    00073     return DoReflect ? reflector( Bits,x ) : x;
    00074
    00075 }
    00076
    00078 static int makecrctable32(ULONG *crctable,size_t Bits,ULONG TruncPoly,BOOL Reflect)
    00079 {
    00080
    00081   // factor-out constants to avoid recalculation
    00082   const value_type     fast_hi_bit = 1ul << ( Bits - 1u );
    00083   unsigned char const  byte_hi_bit = 1u << (CHAR_BIT - 1u);
    00084
    00085   // loop over every possible dividend value
    00086   unsigned char  dividend = 0;
    00087     value_type  remainder ;
    00088     unsigned char mask;
    00089
    00090     if(Bits > 32){
    00091         return edk_FAILED;
    00092     }
    00093
    00094   do
    00095   {
    00096         remainder = 0;
    00097
    00098
    00099     // go through all the dividend's bits
    00100     for ( mask = byte_hi_bit ; mask ; mask >>= 1 )
    00101     {
    00102       // check if divisor fits
    00103       if ( dividend & mask )
    00104       {
    00105           remainder ^= fast_hi_bit;
    00106       }
    00107
    00108       // do polynominal division
    00109       if ( remainder & fast_hi_bit )
    00110       {
    00111           remainder <<= 1;
    00112           remainder ^= TruncPoly;
    00113       }
    00114       else
    00115       {
    00116           remainder <<= 1;
    00117       }
    00118     }
    00119
    00120     //crctable[ crc_helper<CHAR_BIT, Reflect>::reflect(dividend) ]
    00121     // = crc_helper<Bits, Reflect>::reflect( remainder );
    00122         crctable[ reflection(Reflect,CHAR_BIT,dividend) ]
    00123             = reflection(Reflect,Bits,remainder);
    00124   }
    00125   while ( ++dividend );
    00126
    00127     return edk_SUCCEEDED;
    00128 }
    00129
    00131 static int makecrctable16(USHORT *crctable,size_t Bits,ULONG TruncPoly,BOOL Reflect)
    00132 {
    00133
    00134
    00135   // factor-out constants to avoid recalculation
    00136   const value_type16     fast_hi_bit = (const value_type16)(1u << ( Bits - 1u ));
    00137   unsigned char const  byte_hi_bit = 1u << (CHAR_BIT - 1u);
    00138
    00139   // loop over every possible dividend value
    00140   unsigned char  dividend = 0;
    00141     value_type16  remainder ;
    00142     unsigned char mask;
    00143
    00144     if(Bits > 16){
    00145         return edk_FAILED;
    00146     }
    00147
    00148   do
    00149   {
    00150         remainder = 0;
    00151
    00152
    00153     // go through all the dividend's bits
    00154     for ( mask = byte_hi_bit ; mask ; mask >>= 1 )
    00155     {
    00156       // check if divisor fits
    00157       if ( dividend & mask )
    00158       {
    00159           remainder ^= fast_hi_bit;
    00160       }
    00161
    00162       // do polynominal division
    00163       if ( remainder & fast_hi_bit )
    00164       {
    00165           remainder <<= 1;
    00166           remainder ^= TruncPoly;
    00167       }
    00168       else
    00169       {
    00170           remainder <<= 1;
    00171       }
    00172     }
    00173
    00174     //crctable[ crc_helper<CHAR_BIT, Reflect>::reflect(dividend) ]
    00175     // = crc_helper<Bits, Reflect>::reflect( remainder );
    00176         crctable[ reflection(Reflect,CHAR_BIT,dividend) ]
    00177             = (USHORT)reflection(Reflect,Bits,remainder);
    00178   }
    00179   while ( ++dividend );
    00180
    00181     return edk_SUCCEEDED;
    00182 }
    00183 /*
    00184 static Loader32(DKC_CRC *p,const BYTE *pBuffer,size_t size){
    00185
    00186 }
    00187 static Loader16(DKC_CRC *p,const BYTE *pBuffer,size_t size){
    00188
    00189 }*/
    00190
    00191 /* 勝手にプール */
    00192
    00193 static USHORT *get_crc16left(){
    00194
    00195 }
    00196
    00197 static USHORT *get_crc16right(){
    00198
    00199 }
    00200 static ULONG *get_crc32left(){
    00201
    00202 }
    00203 static ULONG *get_crc32right(){
    00204
    00205 }
    00206
    00207 static USHORT *get_crc_ccitt(){
    00208
    00209 }
    00210 static USHORT *get_crc_xmodem(){
    00211
    00212 }
    00213
    00214 size_t WINAPI dkcCRCGetUseTableSize(size_t Bits){
    00215     //手抜き演算〜〜
    00216     size_t t;
    00217     if(Bits <= 16){
    00218         t = sizeof(USHORT) * 0x100;
    00219     }else if(Bits <= 32){
    00220         t = sizeof(ULONG) * 0x100;
    00221     }else{
    00222         t = 0;
    00223     }
    00224     return t;
    00225 }
    00226
    00227 DKC_CRC *WINAPI dkcAllocCRC( size_t Bits, ULONG TruncPoly,
    00228            ULONG InitRem, ULONG FinalXor,
    00229            dkctBOOL ReflectIn, dkctBOOL ReflectRem)
    00230 {
    00231     DKC_CRC *p = (DKC_CRC *)dkcAllocate(sizeof(DKC_CRC));
    00232     void *pt;
    00233
    00234     if(NULL==p){
    00235         return NULL;
    00236     }
    00237     pt = dkcAllocate(dkcCRCGetUseTableSize(Bits));
    00238     if(NULL==pt){
    00239         goto Error;
    00240     }
    00241     dkcCRCInit(p,pt,Bits,TruncPoly,InitRem,FinalXor,ReflectIn,ReflectRem);
    00242
    00243     return p;
    00244
    00245 Error:
    00246     dkcFree((void **)&p);
    00247     return NULL;
    00248 }
    00249
    00250 DKC_CRC* WINAPI dkcAllocCRC_32left(){
    00251     return dkcAllocCRC(32, 0xEDB88320, 0xFFFFFFFF, 0xFFFFFFFF, FALSE, FALSE);
    00252
    00253 }
    00254
    00255 DKC_CRC* WINAPI dkcAllocCRC_32right(){
    00256     //バグ ... 値を治す
    00257     return dkcAllocCRC(32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, TRUE, TRUE);
    00258 }
    00259 DKC_CRC* WINAPI dkcAllocCRC_ansi16left(){
    00260     return dkcAllocCRC(16, 0x8005, 0, 0, TRUE,TRUE);
    00261 }
    00262
    00263 DKC_CRC* WINAPI dkcAllocCRC_ansi16right(){
    00264     return dkcAllocCRC(16, 0xa001, 0, 0, FALSE,FALSE);
    00265 }
    00266
    00267 DKC_CRC* WINAPI dkcAllocCRC_ccitt_left(){
    00268     return dkcAllocCRC(16, 0x1021, 0xFFFF, 0, FALSE,FALSE);
    00269 }
    00270 DKC_CRC* WINAPI dkcAllocCRC_ccitt_right(){
    00271     return dkcAllocCRC(16, 0x8005, 0xFFFF, 0, TRUE,TRUE);
    00272 }
    00273 DKC_CRC *WINAPI dkcAllocCRC_7left(){
    00274     return dkcAllocCRC(16, 0x51, 0xFFFF, 0, FALSE,FALSE);
    00275 }
    00276 DKC_CRC *WINAPI dkcAllocCRC_7right(){
    00277     return dkcAllocCRC(16, 0x8a, 0xFFFF, 0, TRUE,TRUE);
    00278 }
    00279
    00280 DKC_CRC* WINAPI dkcAllocCRC_xmodem(){
    00281     return dkcAllocCRC(16, 0x8408, 0, 0, TRUE,TRUE);
    00282 }
    00283 /*
    00284 bool CheckTable(DKC_CRC *p)
    00285 {
    00286     int i;
    00287         //手抜き演算〜〜
    00288     size_t t;
    00289     if(Bits <= 16){
    00290         t = sizeof(USHORT) * 0x100;
    00291     }else if(Bits <= 32){
    00292         t = sizeof(ULONG) * 0x100;
    00293     }else{
    00294         t = 0;
    00295     }
    00296     dkcCRCGetUseTableSize(p->mBits)
    00297     for(i=0;i<;i++){
    00298         DKC_EXTERN DKC_CRC* WINAPI dkcAllocCRC_32left();
    00299
    00300 DKC_EXTERN DKC_CRC* WINAPI dkcAllocCRC_32right();
    00301
    00302 DKC_EXTERN DKC_CRC* WINAPI dkcAllocCRC_ansi16left();
    00303
    00304 DKC_EXTERN DKC_CRC* WINAPI dkcAllocCRC_ansi16right();
    00305
    00306 DKC_EXTERN DKC_CRC* WINAPI dkcAllocCRC_ccitt_left();
    00307
    00308 DKC_EXTERN DKC_CRC* WINAPI dkcAllocCRC_ccitt_right();
    00309
    00310 DKC_EXTERN DKC_CRC* WINAPI dkcAllocCRC_xmodem();
    00311
    00312     }
    00313
    00314     dkcCRCFree(&p);
    00315 }
    00316
    00317 dkcCheckTable(HOGE){
    00318
    00319 }
    00320
    00321 DKC_CRC *WINAPI dkcAllocCRC_
    00322 */
    00323
    00324 int WINAPI dkcFreeCRC(DKC_CRC **pp){
    00325     dkcFree((void **)&((*pp)->mTable));
    00326     return dkcFree((void **)pp);
    00327 }
    00328
    00329 //int WINAPI dkcCRCInit(DKC_CRC *p,ULONG buffer[256],
    00330 int WINAPI dkcCRCInit(DKC_CRC *p,void *buffer,
    00331                      size_t Bits, ULONG TruncPoly,
    00332            ULONG InitRem, ULONG FinalXor,
    00333            dkctBOOL ReflectIn, dkctBOOL ReflectRem )
    00334 {
    00335     int r;
    00336
    00337     //初期値
    00338     p->mR = reflection(ReflectIn,Bits,InitRem);
    00339     //処理結果
    00340     p->mResult = 0;
    00341     //テーブルへのポインタ
    00342     p->mTable = buffer;
    00343
    00344     p->mBits = Bits;
    00345     p->mTruncPoly = TruncPoly;
    00346     p->mInitRem = InitRem;
    00347     p->mFinalXor = FinalXor;
    00348     p->mReflectIn = ReflectIn;
    00349     p->mReflectRem = ReflectRem;
    00350
    00351
    00352
    00353     if(Bits <= 16){
    00354         r = makecrctable16((USHORT *)buffer,Bits,TruncPoly,ReflectIn);
    00355         //p->mLoader = Loader16;
    00356     }else if(Bits <= 32){
    00357         r = makecrctable32((ULONG *)buffer,Bits,TruncPoly,ReflectIn);
    00358         //p->mLoader = Loader32;
    00359     }else{
    00360         r = edk_FAILED;
    00361     }
    00362     return r;
    00363
    00364 }
    00365
    00366 void WINAPI dkcCRCLoad(DKC_CRC *p,const BYTE *pBuffer,size_t size)
    00367 {
    00368     unsigned char const * const  b = (unsigned char const *)pBuffer;
    00369     dkcCRCLoadBlock(p, b, b + size );
    00370
    00371 }
    00372
    00373 typedef union dkc_local_ptr_offset_union{
    00374     ULONG *pt32;
    00375     USHORT *pt16;
    00376 }OFFSET_PTR_UNION;
    00377
    00378 typedef union dkc_local_offset_union{
    00379     ULONG t32;
    00380     USHORT t16;
    00381 }OFFSET_UNION;
    00382
    00383
    00384 void WINAPI dkcCRCLoadBlock(DKC_CRC *pobj,const void *bytes_begin,const void *bytes_end)
    00385 {
    00386     unsigned char const * p = (unsigned char const *)bytes_begin;
    00387
    00388   unsigned char byte_index;
    00389     //for 32bit
    00390     //ULONG *pTable32 = (ULONG *)pobj->mTable;
    00391     //for 16bit
    00392     //USHORT *pTable16 = (ULONG *)pobj->mTable;
    00393
    00394
    00395
    00396     //general purpose
    00397     size_t Bits = pobj->mBits;
    00398     BOOL DoReflect = pobj->mReflectIn;
    00399
    00400     USHORT *usp;
    00401     ULONG *ulp;
    00402     ULONG rem;
    00403
    00404     ulp = (ULONG *)pobj->mTable;
    00405     usp = (USHORT *)ulp;
    00406
    00407     //もし、おかしな値になったらエンディアン系を疑ってネ＾＾；
    00408     rem = pobj->mR;
    00409
    00410
    00411     if(Bits <= 16)
    00412     {//16bit filter
    00413         // Recompute the CRC for each byte passed
    00414         for (; p < (const BYTE *)bytes_end ; ++p )
    00415         {
    00416             // Compare the new byte with the remainder's higher bits to
    00417             // get the new bits, shift out the remainder's current higher
    00418             // bits, and update the remainder with the polynominal division
    00419             // of the new bits.
    00420             byte_index = index( rem, *p ,Bits,DoReflect);
    00421             rem = (USHORT)shift( rem , DoReflect);
    00422             rem ^= usp[ byte_index ];
    00423         }
    00424
    00425         pobj->mR = rem & mask_value(Bits);
    00426
    00427     }else if(Bits <= 32)
    00428     {//32bit filter
    00429         for (; p < (const BYTE *)bytes_end ; ++p )
    00430         {
    00431
    00432             byte_index = index( rem, *p ,Bits,DoReflect);
    00433             rem = shift( rem ,DoReflect);
    00434             rem ^= ulp[ byte_index ];
    00435         }
    00436         pobj->mR = rem;
    00437     }else{
    00438         dkcmFORCE_NOT_ASSERT("dkcCRCLoadBlock中に32ビット以上の計算を要求された");
    00439     }
    00440     /*
    00441     OFFSET_PTR_UNION uni;
    00442     OFFSET_UNION rem;
    00443
    00444     uni.pt32 = (ULONG *)pobj->mTable;
    00445     //もし、おかしな値になったらエンディアン系を疑ってネ＾＾；
    00446     rem.t32 = pobj->mR;
    00447
    00448
    00449     if(Bits <= 16)
    00450     {//16bit filter
    00451         // Recompute the CRC for each byte passed
    00452         for (; p < (const BYTE *)bytes_end ; ++p )
    00453         {
    00454             // Compare the new byte with the remainder's higher bits to
    00455             // get the new bits, shift out the remainder's current higher
    00456             // bits, and update the remainder with the polynominal division
    00457             // of the new bits.
    00458             byte_index = index( rem.t16, *p ,Bits,DoReflect);
    00459             rem.t16 = (USHORT)shift( rem.t16 , DoReflect);
    00460             rem.t16 ^= uni.pt16[ byte_index ];
    00461         }
    00462
    00463         pobj->mR = rem.t16;
    00464
    00465     }else if(Bits <= 32)
    00466     {//32bit filter
    00467         for (; p < (const BYTE *)bytes_end ; ++p )
    00468         {
    00469
    00470             byte_index = index( rem.t32, *p ,Bits,DoReflect);
    00471             rem.t32 = shift( rem.t32 ,DoReflect);
    00472             rem.t32 ^= uni.pt32[ byte_index ];
    00473         }
    00474         pobj->mR = rem.t32;
    00475     }else{
    00476         dkcmFORCE_NOT_ASSERT("dkcCRCLoadBlock中に32ビット以上の計算を要求された");
    00477     }
    00478     */
    00479
    00480
    00481     //  rem.t32 & mask_value(Bits);
    00482 }
    00483
    00484 static DKC_INLINE ULONG get_sigbit(size_t Bits)
    00485 {
    00486     return (( (BYTE)1u ) << ( Bits - 1u )) ;
    00487     //return (~( ~( 0ul ) << Bits )) ;
    00488     //return (~( ~(least( 0u )) << Bits ))
    00489 }
    00490 ULONG WINAPI dkcCRCFinal(DKC_CRC *p){
    00491     BOOL b = (p->mReflectRem != p->mReflectIn);
    00492     size_t Bits = p->mBits;
    00493     ULONG ult = mask_value(Bits);
    00494         //~(0x80000000 >> (Bits ));//( ( 1u ) << ( get_sigbit(Bits) - 1u ) );
    00495     //変数の再利用･･･。本当はしたくないのだが･･･。
    00496     Bits = ( reflection(b,Bits,p->mR) ^ p->mFinalXor ) & ult;
    00497
    00498     p->mResult = Bits;
    00499
    00500     return Bits;
    00501
    00502
    00503     //reflect_out_type::reflect(rem_) ^ get_final_xor_value() )
    00504   //   & masking_type::sig_bits_fast;
    00505 }
    00506
    00507 ULONG WINAPI dkcCRCResult(const DKC_CRC *p){
    00508     return p->mResult;
    00509 }