00001
00008 #define DKUTIL_C_CRC_C
00009 #include "dkcCRC.h"
00010
00011 typedef ULONG value_type;
00012 typedef USHORT value_type16;
00013
00014
00015
00016
00017
00018
00019 static DKC_INLINE value_type mask_value( size_t Bits){
00020
00021
00022 size_t b = (0xFFFFFFFF >> (32 - Bits));
00023
00024 return b;
00025
00026
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
00043
00044
00045
00046
00047
00048
00049
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
00067
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
00082 const value_type fast_hi_bit = 1ul << ( Bits - 1u );
00083 unsigned char const byte_hi_bit = 1u << (CHAR_BIT - 1u);
00084
00085
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
00100 for ( mask = byte_hi_bit ; mask ; mask >>= 1 )
00101 {
00102
00103 if ( dividend & mask )
00104 {
00105 remainder ^= fast_hi_bit;
00106 }
00107
00108
00109 if ( remainder & fast_hi_bit )
00110 {
00111 remainder <<= 1;
00112 remainder ^= TruncPoly;
00113 }
00114 else
00115 {
00116 remainder <<= 1;
00117 }
00118 }
00119
00120
00121
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
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
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
00154 for ( mask = byte_hi_bit ; mask ; mask >>= 1 )
00155 {
00156
00157 if ( dividend & mask )
00158 {
00159 remainder ^= fast_hi_bit;
00160 }
00161
00162
00163 if ( remainder & fast_hi_bit )
00164 {
00165 remainder <<= 1;
00166 remainder ^= TruncPoly;
00167 }
00168 else
00169 {
00170 remainder <<= 1;
00171 }
00172 }
00173
00174
00175
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
00185
00186
00187
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
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 int WINAPI dkcFreeCRC(DKC_CRC **pp){
00325 dkcFree((void **)&((*pp)->mTable));
00326 return dkcFree((void **)pp);
00327 }
00328
00329
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
00356 }else if(Bits <= 32){
00357 r = makecrctable32((ULONG *)buffer,Bits,TruncPoly,ReflectIn);
00358
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
00390
00391
00392
00393
00394
00395
00396
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 {
00413
00414 for (; p < (const BYTE *)bytes_end ; ++p )
00415 {
00416
00417
00418
00419
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 {
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
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 }
00483
00484 static DKC_INLINE ULONG get_sigbit(size_t Bits)
00485 {
00486 return (( (BYTE)1u ) << ( Bits - 1u )) ;
00487
00488
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
00495
00496 Bits = ( reflection(b,Bits,p->mR) ^ p->mFinalXor ) & ult;
00497
00498 p->mResult = Bits;
00499
00500 return Bits;
00501
00502
00503
00504
00505 }
00506
00507 ULONG WINAPI dkcCRCResult(const DKC_CRC *p){
00508 return p->mResult;
00509 }