"Fossies" - the Fresh Open Source Software Archive

Member "unrar/hash.cpp" (4 May 2022, 3225 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "hash.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "rar.hpp"
    2 
    3 void HashValue::Init(HASH_TYPE Type)
    4 {
    5   HashValue::Type=Type;
    6 
    7   // Zero length data CRC32 is 0. It is important to set it when creating
    8   // headers with no following data like directories or symlinks.
    9   if (Type==HASH_RAR14 || Type==HASH_CRC32)
   10     CRC32=0;
   11   if (Type==HASH_BLAKE2)
   12   {
   13     // dd0e891776933f43c7d032b08a917e25741f8aa9a12c12e1cac8801500f2ca4f
   14     // is BLAKE2sp hash of empty data. We init the structure to this value,
   15     // so if we create a file or service header with no following data like
   16     // "file copy" or "symlink", we set the checksum to proper value avoiding
   17     // additional header type or size checks when extracting.
   18     static byte EmptyHash[32]={
   19       0xdd, 0x0e, 0x89, 0x17, 0x76, 0x93, 0x3f, 0x43,
   20       0xc7, 0xd0, 0x32, 0xb0, 0x8a, 0x91, 0x7e, 0x25,
   21       0x74, 0x1f, 0x8a, 0xa9, 0xa1, 0x2c, 0x12, 0xe1,
   22       0xca, 0xc8, 0x80, 0x15, 0x00, 0xf2, 0xca, 0x4f
   23     };
   24     memcpy(Digest,EmptyHash,sizeof(Digest));
   25   }
   26 }
   27 
   28 
   29 bool HashValue::operator == (const HashValue &cmp)
   30 {
   31   if (Type==HASH_NONE || cmp.Type==HASH_NONE)
   32     return true;
   33   if (Type==HASH_RAR14 && cmp.Type==HASH_RAR14 || 
   34       Type==HASH_CRC32 && cmp.Type==HASH_CRC32)
   35     return CRC32==cmp.CRC32;
   36   if (Type==HASH_BLAKE2 && cmp.Type==HASH_BLAKE2)
   37     return memcmp(Digest,cmp.Digest,sizeof(Digest))==0;
   38   return false;
   39 }
   40 
   41 
   42 DataHash::DataHash()
   43 {
   44   blake2ctx=NULL;
   45   HashType=HASH_NONE;
   46 #ifdef RAR_SMP
   47   ThPool=NULL;
   48   MaxThreads=0;
   49 #endif
   50 }
   51 
   52 
   53 DataHash::~DataHash()
   54 {
   55 #ifdef RAR_SMP
   56   delete ThPool;
   57 #endif
   58   cleandata(&CurCRC32, sizeof(CurCRC32));
   59   if (blake2ctx!=NULL)
   60   {
   61     cleandata(blake2ctx, sizeof(blake2sp_state));
   62     delete blake2ctx;
   63   }
   64 }
   65 
   66 
   67 void DataHash::Init(HASH_TYPE Type,uint MaxThreads)
   68 {
   69   if (blake2ctx==NULL)
   70     blake2ctx=new blake2sp_state;
   71   HashType=Type;
   72   if (Type==HASH_RAR14)
   73     CurCRC32=0;
   74   if (Type==HASH_CRC32)
   75     CurCRC32=0xffffffff; // Initial CRC32 value.
   76   if (Type==HASH_BLAKE2)
   77     blake2sp_init(blake2ctx);
   78 #ifdef RAR_SMP
   79   DataHash::MaxThreads=Min(MaxThreads,MaxHashThreads);
   80 #endif
   81 }
   82 
   83 
   84 void DataHash::Update(const void *Data,size_t DataSize)
   85 {
   86 #ifndef SFX_MODULE
   87   if (HashType==HASH_RAR14)
   88     CurCRC32=Checksum14((ushort)CurCRC32,Data,DataSize);
   89 #endif
   90   if (HashType==HASH_CRC32)
   91     CurCRC32=CRC32(CurCRC32,Data,DataSize);
   92 
   93   if (HashType==HASH_BLAKE2)
   94   {
   95 #ifdef RAR_SMP
   96     if (MaxThreads>1 && ThPool==NULL)
   97       ThPool=new ThreadPool(BLAKE2_THREADS_NUMBER);
   98     blake2ctx->ThPool=ThPool;
   99     blake2ctx->MaxThreads=MaxThreads;
  100 #endif
  101     blake2sp_update( blake2ctx, (byte *)Data, DataSize);
  102   }
  103 }
  104 
  105 
  106 void DataHash::Result(HashValue *Result)
  107 {
  108   Result->Type=HashType;
  109   if (HashType==HASH_RAR14)
  110     Result->CRC32=CurCRC32;
  111   if (HashType==HASH_CRC32)
  112     Result->CRC32=CurCRC32^0xffffffff;
  113   if (HashType==HASH_BLAKE2)
  114   {
  115     // Preserve the original context, so we can continue hashing if necessary.
  116     blake2sp_state res=*blake2ctx;
  117     blake2sp_final(&res,Result->Digest);
  118   }
  119 }
  120 
  121 
  122 uint DataHash::GetCRC32()
  123 {
  124   return HashType==HASH_CRC32 ? CurCRC32^0xffffffff : 0;
  125 }
  126 
  127 
  128 bool DataHash::Cmp(HashValue *CmpValue,byte *Key)
  129 {
  130   HashValue Final;
  131   Result(&Final);
  132   if (Key!=NULL)
  133     ConvertHashToMAC(&Final,Key);
  134   return Final==*CmpValue;
  135 }