⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unrarlib.c

📁 RAR的解压缩算法
💻 C
📖 第 1 页 / 共 4 页
字号:
                        "               jae  else_A\n"
                        "\n"
                        "                  cmpl 13*4(%%edx), %%eax\n"
                        "                  jae  else_7\n"
                        "                  movl  $13, %0\n"
                        "                  jmp  next_7\n"
                        "                 else_7:       \n"
                        "                  movl  $14, %0\n"
                        "                 next_7:\n"
                        "\n"
                        "               jmp  next_A\n"
                        "              else_A:          \n"
                        "               movl  $15, %0   \n"
                        "              next_A:\n"
                        "          \n"
                        "        next_D:                             \n"
                        "    next_G:\n":"=g" (I),
                        "=r" (N):"eax" ((long) BitField),
                        "edx" ((long) Deco->DecodeLen):"memory");

#else
  N = BitField & 0xFFFE;
  if (N < Deco->DecodeLen[8])
  {
    if (N < Deco->DecodeLen[4])
    {
      if (N < Deco->DecodeLen[2])
      {
        if (N < Deco->DecodeLen[1])
          I = 1;
        else
          I = 2;
      }
      else
      {
        if (N < Deco->DecodeLen[3])
          I = 3;
        else
          I = 4;
      }
    }
    else
    {
      if (N < Deco->DecodeLen[6])
      {
        if (N < Deco->DecodeLen[5])
          I = 5;
        else
          I = 6;
      }
      else
      {
        if (N < Deco->DecodeLen[7])
          I = 7;
        else
          I = 8;
      }
    }
  }
  else
  {
    if (N < Deco->DecodeLen[12])
    {
      if (N < Deco->DecodeLen[10])
      {
        if (N < Deco->DecodeLen[9])
          I = 9;
        else
          I = 10;
      }
      else
      {
        if (N < Deco->DecodeLen[11])
          I = 11;
        else
          I = 12;
      }
    }
    else
    {
      if (N < Deco->DecodeLen[14])
      {
        if (N < Deco->DecodeLen[13])
          I = 13;
        else
          I = 14;

      }
      else
      {
        I = 15;
      }
    }

  }
#endif

  AddBits (I);
  if ((N =
       Deco->DecodePos[I] + ((N - Deco->DecodeLen[I - 1]) >> (16 - I))) >=
      Deco->MaxNum)
    N = 0;
  Number = Deco->DecodeNum[N];
}


void
UnpInitData ()
{
  InAddr = InBit = 0;
  if (!(NewLhd.Flags & LHD_SOLID))
  {
    ChannelDelta = CurChannel = 0;

#ifdef _USE_ASM

    asm volatile ("        cld\n" /* increment EDI and ESI */
                  "        movb $0x00, %%al\n" "        movl %0, %%ecx\n" "        movl %1, %%edi\n" "        rep\n" "        stosb\n"  /* clear memory */
                  "\n" "        movl %2, %%ecx\n" "        mov  %3, %%edi\n" "        rep\n" "        stosb\n"  /* clear memory */
                  "\n" "        movl %4, %%ecx\n" "        movl %5, %%edi\n" "        rep\n" "        stosb\n"  /* clear memory */
                  "\n"
                  "        movl $0, (OldDistPtr)\n"
                  "        movl $0, (LastDist)\n"
                  "        movl $0, (LastLength)\n"
                  "        movl $0, (UnpPtr)\n"
                  "        movl $0, (WrPtr)\n"
                  "        movl $0, (OldDistPtr)\n"
                  "        movl $0, (LastLength)\n"
                  "        movl $0, (LastDist)\n"
                  "        movl $0, (UnpPtr)\n"
                  "        movl $0, (WrPtr)\n"::"m" ((long) sizeof (AudV)),
                  "m" ((long) AudV), "m" ((long) sizeof (OldDist)),
                  "m" ((long) OldDist), "m" ((long) sizeof (UnpOldTable)),
                  "m" ((long) UnpOldTable):"memory", "edi", "eax", "ecx");

    memset (UnpBuf, 0, MAXWINSIZE);

#else /* unix/linux on non-i386 cpu  */
    memset (AudV, 0, sizeof (AudV));
    memset (OldDist, 0, sizeof (OldDist));
    OldDistPtr = 0;
    LastDist = LastLength = 0;
    memset (UnpBuf, 0, MAXWINSIZE);
    memset (UnpOldTable, 0, sizeof (UnpOldTable));
    UnpPtr = WrPtr = 0;
#endif

  }
}


UBYTE
DecodeAudio (int Delta)
{
  struct AudioVariables *V;
  unsigned int Ch;
  unsigned int NumMinDif, MinDif;
  int PCh, I;

  V = &AudV[CurChannel];
  V->ByteCount++;
  V->D4 = V->D3;
  V->D3 = V->D2;
  V->D2 = V->LastDelta - V->D1;
  V->D1 = V->LastDelta;
  PCh = 8 * V->LastChar + V->K1 * V->D1 + V->K2 * V->D2 +
    V->K3 * V->D3 + V->K4 * V->D4 + V->K5 * ChannelDelta;
  PCh = (PCh >> 3) & 0xFF;

  Ch = PCh - Delta;

  I = ((signed char) Delta) << 3;

  V->Dif[0] += abs (I);
  V->Dif[1] += abs (I - V->D1);
  V->Dif[2] += abs (I + V->D1);
  V->Dif[3] += abs (I - V->D2);
  V->Dif[4] += abs (I + V->D2);
  V->Dif[5] += abs (I - V->D3);
  V->Dif[6] += abs (I + V->D3);
  V->Dif[7] += abs (I - V->D4);
  V->Dif[8] += abs (I + V->D4);
  V->Dif[9] += abs (I - ChannelDelta);
  V->Dif[10] += abs (I + ChannelDelta);

  ChannelDelta = V->LastDelta = (signed char) (Ch - V->LastChar);
  V->LastChar = Ch;

  if ((V->ByteCount & 0x1F) == 0)
  {
    MinDif = V->Dif[0];
    NumMinDif = 0;
    V->Dif[0] = 0;
    for (I = 1; (unsigned int) I < sizeof (V->Dif) / sizeof (V->Dif[0]); I++)
    {
      if (V->Dif[I] < MinDif)
      {
        MinDif = V->Dif[I];
        NumMinDif = I;
      }
      V->Dif[I] = 0;
    }
    switch (NumMinDif)
    {
    case 1:
      if (V->K1 >= -16)
        V->K1--;
      break;
    case 2:
      if (V->K1 < 16)
        V->K1++;
      break;
    case 3:
      if (V->K2 >= -16)
        V->K2--;
      break;
    case 4:
      if (V->K2 < 16)
        V->K2++;
      break;
    case 5:
      if (V->K3 >= -16)
        V->K3--;
      break;
    case 6:
      if (V->K3 < 16)
        V->K3++;
      break;
    case 7:
      if (V->K4 >= -16)
        V->K4--;
      break;
    case 8:
      if (V->K4 < 16)
        V->K4++;
      break;
    case 9:
      if (V->K5 >= -16)
        V->K5--;
      break;
    case 10:
      if (V->K5 < 16)
        V->K5++;
      break;
    }
  }
  return (UBYTE) Ch;
}


/* CRCCrypt Code - decryption engine starts here */
#define NROUNDS 32

#define rol(x,n)  (((x)<<(n)) | ((x)>>(8*sizeof(x)-(n))))
#define ror(x,n)  (((x)>>(n)) | ((x)<<(8*sizeof(x)-(n))))

#define substLong(t) ( (UDWORD)SubstTable[(int)t&255] | \
           ((UDWORD)SubstTable[(int)(t>> 8)&255]<< 8) | \
           ((UDWORD)SubstTable[(int)(t>>16)&255]<<16) | \
           ((UDWORD)SubstTable[(int)(t>>24)&255]<<24) )


UDWORD CRCTab[256];

UBYTE SubstTable[256];
UBYTE InitSubstTable[256] = {
  215, 19, 149, 35, 73, 197, 192, 205, 249, 28, 16, 119, 48, 221, 2, 42,
  232, 1, 177, 233, 14, 88, 219, 25, 223, 195, 244, 90, 87, 239, 153, 137,
  255, 199, 147, 70, 92, 66, 246, 13, 216, 40, 62, 29, 217, 230, 86, 6,
  71, 24, 171, 196, 101, 113, 218, 123, 93, 91, 163, 178, 202, 67, 44, 235,
  107, 250, 75, 234, 49, 167, 125, 211, 83, 114, 157, 144, 32, 193, 143, 36,
  158, 124, 247, 187, 89, 214, 141, 47, 121, 228, 61, 130, 213, 194, 174, 251,
  97, 110, 54, 229, 115, 57, 152, 94, 105, 243, 212, 55, 209, 245, 63, 11,
  164, 200, 31, 156, 81, 176, 227, 21, 76, 99, 139, 188, 127, 17, 248, 51,
  207, 120, 189, 210, 8, 226, 41, 72, 183, 203, 135, 165, 166, 60, 98, 7,
  122, 38, 155, 170, 69, 172, 252, 238, 39, 134, 59, 128, 236, 27, 240, 80,
  131, 3, 85, 206, 145, 79, 154, 142, 159, 220, 201, 133, 74, 64, 20, 129,
  224, 185, 138, 103, 173, 182, 43, 34, 254, 82, 198, 151, 231, 180, 58, 10,
  118, 26, 102, 12, 50, 132, 22, 191, 136, 111, 162, 179, 45, 4, 148, 108,
  161, 56, 78, 126, 242, 222, 15, 175, 146, 23, 33, 241, 181, 190, 77, 225,
  0, 46, 169, 186, 68, 95, 237, 65, 53, 208, 253, 168, 9, 18, 100, 52,
  116, 184, 160, 96, 109, 37, 30, 106, 140, 104, 150, 5, 204, 117, 112, 84
};

UDWORD Key[4];


void
EncryptBlock (UBYTE * Buf)
{
  int I;

  UDWORD A, B, C, D, T, TA, TB;
#ifdef NON_INTEL_BYTE_ORDER
  A = ((UDWORD) Buf[0] | ((UDWORD) Buf[1] << 8) | ((UDWORD) Buf[2] << 16) |
       ((UDWORD) Buf[3] << 24)) ^ Key[0];
  B = ((UDWORD) Buf[4] | ((UDWORD) Buf[5] << 8) | ((UDWORD) Buf[6] << 16) |
       ((UDWORD) Buf[7] << 24)) ^ Key[1];
  C = ((UDWORD) Buf[8] | ((UDWORD) Buf[9] << 8) | ((UDWORD) Buf[10] << 16) |
       ((UDWORD) Buf[11] << 24)) ^ Key[2];
  D = ((UDWORD) Buf[12] | ((UDWORD) Buf[13] << 8) | ((UDWORD) Buf[14] << 16) |
       ((UDWORD) Buf[15] << 24)) ^ Key[3];
#else
  UDWORD *BufPtr;
  BufPtr = (UDWORD *) Buf;
  A = BufPtr[0] ^ Key[0];
  B = BufPtr[1] ^ Key[1];
  C = BufPtr[2] ^ Key[2];
  D = BufPtr[3] ^ Key[3];
#endif
  for (I = 0; I < NROUNDS; I++)
  {
    T = ((C + rol (D, 11)) ^ Key[I & 3]);
    TA = A ^ substLong (T);
    T = ((D ^ rol (C, 17)) + Key[I & 3]);
    TB = B ^ substLong (T);
    A = C;
    B = D;
    C = TA;
    D = TB;
  }
#ifdef NON_INTEL_BYTE_ORDER
  C ^= Key[0];
  Buf[0] = (UBYTE) C;
  Buf[1] = (UBYTE) (C >> 8);
  Buf[2] = (UBYTE) (C >> 16);
  Buf[3] = (UBYTE) (C >> 24);
  D ^= Key[1];
  Buf[4] = (UBYTE) D;
  Buf[5] = (UBYTE) (D >> 8);
  Buf[6] = (UBYTE) (D >> 16);
  Buf[7] = (UBYTE) (D >> 24);
  A ^= Key[2];
  Buf[8] = (UBYTE) A;
  Buf[9] = (UBYTE) (A >> 8);
  Buf[10] = (UBYTE) (A >> 16);
  Buf[11] = (UBYTE) (A >> 24);
  B ^= Key[3];
  Buf[12] = (UBYTE) B;
  Buf[13] = (UBYTE) (B >> 8);
  Buf[14] = (UBYTE) (B >> 16);
  Buf[15] = (UBYTE) (B >> 24);
#else
  BufPtr[0] = C ^ Key[0];
  BufPtr[1] = D ^ Key[1];
  BufPtr[2] = A ^ Key[2];
  BufPtr[3] = B ^ Key[3];
#endif
  UpdKeys (Buf);
}


void
DecryptBlock (UBYTE * Buf)
{
  int I;
  UBYTE InBuf[16];
  UDWORD A, B, C, D, T, TA, TB;
#ifdef NON_INTEL_BYTE_ORDER
  A = ((UDWORD) Buf[0] | ((UDWORD) Buf[1] << 8) | ((UDWORD) Buf[2] << 16) |
       ((UDWORD) Buf[3] << 24)) ^ Key[0];
  B = ((UDWORD) Buf[4] | ((UDWORD) Buf[5] << 8) | ((UDWORD) Buf[6] << 16) |
       ((UDWORD) Buf[7] << 24)) ^ Key[1];
  C = ((UDWORD) Buf[8] | ((UDWORD) Buf[9] << 8) | ((UDWORD) Buf[10] << 16) |
       ((UDWORD) Buf[11] << 24)) ^ Key[2];
  D = ((UDWORD) Buf[12] | ((UDWORD) Buf[13] << 8) | ((UDWORD) Buf[14] << 16) |
       ((UDWORD) Buf[15] << 24)) ^ Key[3];
#else
  UDWORD *BufPtr;
  BufPtr = (UDWORD *) Buf;
  A = BufPtr[0] ^ Key[0];       /* xxx may be this can be       */
  B = BufPtr[1] ^ Key[1];       /* optimized in assembler       */
  C = BufPtr[2] ^ Key[2];
  D = BufPtr[3] ^ Key[3];
#endif
  memcpy (InBuf, Buf, sizeof (InBuf));
  for (I = NROUNDS - 1; I >= 0; I--)
  {
    T = ((C + rol (D, 11)) ^ Key[I & 3]);
    TA = A ^ substLong (T);
    T = ((D ^ rol (C, 17)) + Key[I & 3]);
    TB = B ^ substLong (T);
    A = C;
    B = D;
    C = TA;
    D = TB;
  }
#ifdef NON_INTEL_BYTE_ORDER
  C ^= Key[0];
  Buf[0] = (UBYTE) C;
  Buf[1] = (UBYTE) (C >> 8);
  Buf[2] = (UBYTE) (C >> 16);
  Buf[3] = (UBYTE) (C >> 24);
  D ^= Key[1];
  Buf[4] = (UBYTE) D;
  Buf[5] = (UBYTE) (D >> 8);
  Buf[6] = (UBYTE) (D >> 16);
  Buf[7] = (UBYTE) (D >> 24);
  A ^= Key[2];
  Buf[8] = (UBYTE) A;
  Buf[9] = (UBYTE) (A >> 8);
  Buf[10] = (UBYTE) (A >> 16);
  Buf[11] = (UBYTE) (A >> 24);
  B ^= Key[3];
  Buf[12] = (UBYTE) B;
  Buf[13] = (UBYTE) (B >> 8);
  Buf[14] = (UBYTE) (B >> 16);
  Buf[15] = (UBYTE) (B >> 24);
#else
  BufPtr[0] = C ^ Key[0];
  BufPtr[1] = D ^ Key[1];
  BufPtr[2] = A ^ Key[2];
  BufPtr[3] = B ^ Key[3];
#endif
  UpdKeys (InBuf);
}


void
UpdKeys (UBYTE * Buf)
{
  int I;
  for (I = 0; I < 16; I += 4)
  {
    Key[0] ^= CRCTab[Buf[I]];   /* xxx may be I'll rewrite this */
    Key[1] ^= CRCTab[Buf[I + 1]]; /* in asm for speedup           */
    Key[2] ^= CRCTab[Buf[I + 2]];
    Key[3] ^= CRCTab[Buf[I + 3]];
  }
}

void
SetCryptKeys (char *Password)
{
  unsigned int I, J, K, PswLength;
  unsigned char N1, N2;
  unsigned char Psw[256];

#if !defined _USE_ASM
  UBYTE Ch;
#endif

  SetOldKeys (Password);

  Key[0] = 0xD3A3B879L;
  Key[1] = 0x3F6D12F7L;
  Key[2] = 0x7515A235L;
  Key[3] = 0xA4E7F123L;
  memset (Psw, 0, sizeof (Psw));
  strcpy ((char *) Psw, Password);
  PswLength = strlen (Password);
  memcpy (SubstTable, InitSubstTable, sizeof (SubstTable));

  for (J = 0; J < 256; J++)
    for (I = 0; I < PswLength; I += 2)
    {
      N2 = (unsigned char) CRCTab[(Psw[I + 1] + J) & 0xFF];
      for (K = 1, N1 = (unsigned char) CRCTab[(Psw[I] - J) & 0xFF];
           (N1 != N2) && (N1 < 256);
           /* I had to add "&& (N1 < 256)", because the system crashed with encrypted RARs */
           N1++, K++)
      {
#ifdef _USE_ASM
        __asm__ __volatile__ ("                    xorl %%ecx, %%ecx\n"
                              "                    movl %2, %%ecx                     /* ecx = N1 */\n"
                              "                    mov %%ebx, %%edx\n"
                              "                    addl %%ecx, %%ebx\n"
                              "\n"
                              "                    addl %0, %%ecx\n"
                              "                    addl %1, %%ecx\n"
                              "                    andl $0x000000FF, %%ecx\n"
                              "                    addl %%ecx, %%edx\n"
                              "                    \n"
                              "                    movb (%%ebx), %%al\n"
                              "                    movb (%%edx), %%ah\n"
                              "\n"
                              "                    movb  %%ah, (%%ebx)     /* and write back */\n"
                              "                    movb  %%al, (%%edx)\n"::"g"
                              ((long) I), "g" ((long) K), "g" ((long) N1),
                              "ebx" ((long) SubstTable):"ecx", "edx");

#else
        /* Swap(&SubstTable[N1],&SubstTable[(N1+I+K)&0xFF]);            */
        Ch = SubstTable[N1];
        SubstTable[N1] = SubstTable[(N1 + I + K) & 0xFF];
        SubstTable[(N1 + I + K) & 0xFF] = Ch;
#endif
      }
    }
  for (I = 0; I < PswLength; I += 16)
    EncryptBlock (&Psw[I]);
}


void
SetOldKeys (char *Password)
{
  UDWORD PswCRC;
  UBYTE Ch;
  PswCRC = CalcCRC32 (0xFFFFFFFFL, (UBYTE *) Password, strlen (Password));
  OldKey[0] = (UWORD) PswCRC;
  OldKey[1] = (UWORD) (PswCRC >> 16);
  OldKey[2] = OldKey[3] = 0;
  PN1 = PN2 = PN3 = 0;
  while ((Ch = *Password) != 0)
  {
    PN1 += Ch;
    PN2 ^= Ch;
    PN3 += Ch;
    PN3 = (UBYTE) rol (PN3, 1);
    OldKey[2] ^= ((UWORD) (Ch ^ CRCTab[Ch]));
    OldKey[3] += ((UWORD) (Ch + (CRCTab[Ch] >> 16)));
    Password++;
  }
}

void
InitCRC (void)
{
  int I, J;
  UDWORD C;
  for (I = 0; I < 256; I++)
  {
    for (C = I, J = 0; J < 8; J++)
      C = (C & 1) ? (C >> 1) ^ 0xEDB88320L : (C >> 1);
    CRCTab[I] = C;
  }
}


uint32_t
CalcCRC32 (uint32_t StartCRC, UBYTE * Addr, UDWORD Size)
{
  unsigned int I;
  for (I = 0; I < Size; I++)
    StartCRC = CRCTab[(UBYTE) StartCRC ^ Addr[I]] ^ (StartCRC >> 8);
  return StartCRC;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -