/* * util.c -- Miscellaneous shared code/data * * Copyright (C) 1997 Pretty Good Privacy, Inc. * * Written by Mark H. Weaver * * $Id: util.c,v 1.11 1997/11/07 00:44:10 mhw Exp $ */ #include #include "util.h" char const hexDigits[] = "0123456789abcdef"; char const radix64Digits[] = #if 0 /* Standard */ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; #else /* Modified form that avoids hard-to-OCR characters */ "ABCDEFGHIJKLMNPQRSTVWXYZabcdehijklmnpqtuwy145689\\^!#$%&*+=/:<>?@"; #endif signed char hexDigitsInv[256]; signed char radix64DigitsInv[256]; /* teun: moved intitialisation of all three CRCPoly's to initUtil() */ /* CRC-CCITT: x^16 + x^12 + x^5 + 1 */ CRCPoly crcCCITTPoly; /* * PRZ's magic 24-bit polynomial - (x+1) * (irreducible of degree 23) * x^24 +x^23 +x^18 +x^17 +x^14 +x^11 +x^10 +x^7 +x^6 +x^5 +x^4 +x^3 +x +1 * (Developed by Neal Glover). Note: this is bit-reversed from the form * used in PGP, 0x1864cfb. */ CRCPoly crc24Poly; /* CRC-32: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 */ CRCPoly crc32Poly; EncodeFormat const hexFormat = { NULL, /* nextFormat */ '-', /* headerTypeChar */ hexDigits, /* digits */ hexDigitsInv, /* digitsInv */ 4, /* bitsPerDigit */ 16, /* radix */ &crcCCITTPoly, /* lineCRC */ &crc32Poly, /* pageCRC */ 8, /* runningCRCBits */ 24, /* runningCRCShift */ 0xFF /* runningCRCMask */ }; EncodeFormat const radix64Format = { &hexFormat, /* nextFormat */ 'A', /* headerTypeChar */ radix64Digits, /* digits */ radix64DigitsInv, /* digitsInv */ 6, /* bitsPerDigit */ 64, /* radix */ &crc24Poly, /* lineCRC */ &crc32Poly, /* pageCRC */ 12, /* runningCRCBits */ 20, /* runningCRCShift */ 0xFFF /* runningCRCMask */ }; EncodeFormat const * firstFormat = &radix64Format; static void InitCRCPoly(CRCPoly *poly) { int i, oneBit; CRC crc = 1; poly->table[0] = 0; for (oneBit = 0x80; oneBit > 0; oneBit >>= 1) { crc = (crc >> 1) ^ ((crc & 1) ? poly->poly : 0); for (i = 0; i < 0x100; i += 2 * oneBit) poly->table[i + oneBit] = poly->table[i] ^ crc; } } CRC CalculateCRC(CRCPoly const *poly, CRC crc, byte const *buffer, size_t length) { while (length--) crc = (crc >> 8) ^ poly->table[(crc & 0xFF) ^ (*buffer++)]; return crc; } CRC ReverseCRC(CRCPoly const *poly, CRC crc, byte b) { int i, highBit = poly->highBit; for (i = 0; i < 8; i++) { if (crc & highBit) /* highBit is 2^(poly->bits-1) */ crc = ((crc ^ poly->poly) << 1) ^ 1; else crc <<= 1; } return crc ^ b; } static void InitDigitsInv(char const *digits, signed char *digitsInv) { int i; for (i = 0; i < 256; i++) digitsInv[i] = -1; for (i = 0; digits[i]; i++) digitsInv[(byte)digits[i]] = i; } /* Returns the number of chars encoded */ int EncodeCheckDigits(EncodeFormat const *fmt, word32 num, int numBits, char *dest) { int destLen = EncodedLength(fmt, numBits); word32 digitMask = fmt->radix - 1; int i; for (i = destLen - 1; i >= 0; i--) { dest[i] = EncodeDigit(fmt, num & digitMask); num >>= fmt->bitsPerDigit; } return destLen; } /* Returns 1 if there's an error */ int DecodeCheckDigits(EncodeFormat const *fmt, char const *src, char **endPtr, int numBits, word32 *valuePtr) { word32 value = 0; int digitValue; int i = EncodedLength(fmt, numBits); while (i--) { digitValue = DecodeDigit(fmt, *src++); if (digitValue < 0) { /* Invalid digit found */ *valuePtr = 0; if (endPtr) *endPtr = NULL; return 1; } value = (value << fmt->bitsPerDigit) | digitValue; } *valuePtr = value; if (endPtr) *endPtr = (char *)src; return 0; } EncodeFormat const *FindFormat(char headerTypeChar) { EncodeFormat const * fmt = firstFormat; while (fmt && fmt->headerTypeChar != headerTypeChar) fmt = fmt->nextFormat; return fmt; } void InitUtil() { /* teun: removed "{ }" for MS VC compile */ crcCCITTPoly.bits = 16; crcCCITTPoly.poly = 0x8408; crcCCITTPoly.highBit = 0x8000; crc24Poly.bits = 24; crc24Poly.poly = 0xdf3261; crc24Poly.highBit = 0x800000; crc32Poly.bits = 32; crc32Poly.poly = 0xedb88320; crc32Poly.highBit = 0x80000000; InitCRCPoly(&crcCCITTPoly); InitCRCPoly(&crc24Poly); InitCRCPoly(&crc32Poly); InitDigitsInv(hexDigits, hexDigitsInv); InitDigitsInv(radix64Digits, radix64DigitsInv); } /* * Local Variables: * tab-width: 4 * End: * vi: ts=4 sw=4 * vim: si */