01/10/2018, 08:14

Chia sẻ thuật toán parse chuỗi hex rất nhanh (max 16bit)

Mình có vọc vạch làm keygen cho một soft thì thấy nó dùng thuật toán này, parse chuỗi hex tối đa 4 ký tự, mình chưa hiểu được cơ sở toán học của nó là gì, thấy hay nên share cho mọi người xem:

unsigned __int16 __cdecl HexToDecimal(std::wstring& cStr)
{
   int currentWChar; // edx@1
   int strLen; // ecx@1
   unsigned __int16 result; // ax@2
   signed int check; // ecx@3
   int encodedWChar; // edx@6
   int index = 0;
   currentWChar = cStr[0];
   strLen = cStr.length();
   if (strLen)
   {
      result = 0;
      if (strLen == 4)
      {
         check = 12;
         while (true)
         {
            currentWChar = cStr[index];
            if ((unsigned __int16)currentWChar < 'a' || (unsigned __int16)currentWChar > 'f')
            {
               if ((unsigned __int16)currentWChar < 'A' || (unsigned __int16)currentWChar > 'F')
               {
                  if ((unsigned __int16)currentWChar < '0' || (unsigned __int16)currentWChar > '9')
                     return 0;
                  encodedWChar = currentWChar + 0xFFD0;
               }
               else
               {
                  encodedWChar = currentWChar + 0xFFC9;
               }
            }
            else
            {
               encodedWChar = currentWChar + 0xFFA9;
            }
            currentWChar = encodedWChar << check;
            check -= 4;
            index++;
            result += currentWChar;
            if (check <= -4)
               return result;
         }
      }
   }
   return 0;
}
*grab popcorn* viết 10:15 ngày 01/10/2018

16 = 2^4
-> 16^x = (2^4)^x = 2^(4*x)

Giả sử có số cần đổi là 1234

Ở vòng lặp đầu
2^12 = left shift 12 bit

FFD0 + 1 ký tự số = 1 0000 0000 0000 (xxxx)
xxxx = giá trị của ký tự số đó
-> FFD0 + ‘1’ = 1 0000 0000 0000 (0001) << 12 = 1 0000 0000 0000 (0001 0000 0000 0000)
Phần trong ngoặc chính bằng 1*16^3. Và vì result chỉ có 16bit nên nó chỉ nhận đúng 16bit kia. Các phần còn lại được bỏ hết.

Tương tự cho các ký tự còn lại
Giải thuật khá hay nhưng chỉ bị bug chỗ nếu strlen != 4 thì ko convert .

Bài liên quan
0