binascii.c
来自「python s60 1.4.5版本的源代码」· C语言 代码 · 共 1,332 行 · 第 1/3 页
C
1,332 行
/* Shift the data into our buffer */
leftchar = (leftchar << 8) | *bin_data;
leftbits += 8;
/* See if there are 6-bit groups ready */
while ( leftbits >= 6 ) {
this_ch = (leftchar >> (leftbits-6)) & 0x3f;
leftbits -= 6;
*ascii_data++ = table_b2a_base64[this_ch];
}
}
if ( leftbits == 2 ) {
*ascii_data++ = table_b2a_base64[(leftchar&3) << 4];
*ascii_data++ = BASE64_PAD;
*ascii_data++ = BASE64_PAD;
} else if ( leftbits == 4 ) {
*ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2];
*ascii_data++ = BASE64_PAD;
}
*ascii_data++ = '\n'; /* Append a courtesy newline */
_PyString_Resize(&rv, (ascii_data -
(unsigned char *)PyString_AsString(rv)));
return rv;
}
static const char doc_a2b_hqx[] = "ascii -> bin, done. Decode .hqx coding";
static PyObject *
binascii_a2b_hqx(PyObject *self, PyObject *args)
{
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
unsigned int leftchar = 0;
PyObject *rv;
int len;
int done = 0;
if ( !PyArg_ParseTuple(args, "t#:a2b_hqx", &ascii_data, &len) )
return NULL;
/* Allocate a string that is too big (fixed later) */
if ( (rv=PyString_FromStringAndSize(NULL, len)) == NULL )
return NULL;
bin_data = (unsigned char *)PyString_AsString(rv);
for( ; len > 0 ; len--, ascii_data++ ) {
/* Get the byte and look it up */
this_ch = table_a2b_hqx[*ascii_data];
if ( this_ch == SKIP )
continue;
if ( this_ch == FAIL ) {
PyErr_SetString((PYTHON_GLOBALS->binascii_Error), "Illegal char");
Py_DECREF(rv);
return NULL;
}
if ( this_ch == DONE ) {
/* The terminating colon */
done = 1;
break;
}
/* Shift it into the buffer and see if any bytes are ready */
leftchar = (leftchar << 6) | (this_ch);
leftbits += 6;
if ( leftbits >= 8 ) {
leftbits -= 8;
*bin_data++ = (leftchar >> leftbits) & 0xff;
leftchar &= ((1 << leftbits) - 1);
}
}
if ( leftbits && !done ) {
PyErr_SetString((PYTHON_GLOBALS->binascii_Incomplete),
"String has incomplete number of bytes");
Py_DECREF(rv);
return NULL;
}
_PyString_Resize(
&rv, (bin_data - (unsigned char *)PyString_AsString(rv)));
if (rv) {
PyObject *rrv = Py_BuildValue("Oi", rv, done);
Py_DECREF(rv);
return rrv;
}
return NULL;
}
static const char doc_rlecode_hqx[] = "Binhex RLE-code binary data";
static PyObject *
binascii_rlecode_hqx(PyObject *self, PyObject *args)
{
unsigned char *in_data, *out_data;
PyObject *rv;
unsigned char ch;
int in, inend, len;
if ( !PyArg_ParseTuple(args, "s#:rlecode_hqx", &in_data, &len) )
return NULL;
/* Worst case: output is twice as big as input (fixed later) */
if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
return NULL;
out_data = (unsigned char *)PyString_AsString(rv);
for( in=0; in<len; in++) {
ch = in_data[in];
if ( ch == RUNCHAR ) {
/* RUNCHAR. Escape it. */
*out_data++ = RUNCHAR;
*out_data++ = 0;
} else {
/* Check how many following are the same */
for(inend=in+1;
inend<len && in_data[inend] == ch &&
inend < in+255;
inend++) ;
if ( inend - in > 3 ) {
/* More than 3 in a row. Output RLE. */
*out_data++ = ch;
*out_data++ = RUNCHAR;
*out_data++ = inend-in;
in = inend-1;
} else {
/* Less than 3. Output the byte itself */
*out_data++ = ch;
}
}
}
_PyString_Resize(&rv, (out_data -
(unsigned char *)PyString_AsString(rv)));
return rv;
}
static const char doc_b2a_hqx[] = "Encode .hqx data";
static PyObject *
binascii_b2a_hqx(PyObject *self, PyObject *args)
{
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
unsigned int leftchar = 0;
PyObject *rv;
int len;
if ( !PyArg_ParseTuple(args, "s#:b2a_hqx", &bin_data, &len) )
return NULL;
/* Allocate a buffer that is at least large enough */
if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL )
return NULL;
ascii_data = (unsigned char *)PyString_AsString(rv);
for( ; len > 0 ; len--, bin_data++ ) {
/* Shift into our buffer, and output any 6bits ready */
leftchar = (leftchar << 8) | *bin_data;
leftbits += 8;
while ( leftbits >= 6 ) {
this_ch = (leftchar >> (leftbits-6)) & 0x3f;
leftbits -= 6;
*ascii_data++ = table_b2a_hqx[this_ch];
}
}
/* Output a possible runt byte */
if ( leftbits ) {
leftchar <<= (6-leftbits);
*ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
}
_PyString_Resize(&rv, (ascii_data -
(unsigned char *)PyString_AsString(rv)));
return rv;
}
static const char doc_rledecode_hqx[] = "Decode hexbin RLE-coded string";
static PyObject *
binascii_rledecode_hqx(PyObject *self, PyObject *args)
{
unsigned char *in_data, *out_data;
unsigned char in_byte, in_repeat;
PyObject *rv;
int in_len, out_len, out_len_left;
if ( !PyArg_ParseTuple(args, "s#:rledecode_hqx", &in_data, &in_len) )
return NULL;
/* Empty string is a special case */
if ( in_len == 0 )
return Py_BuildValue("s", "");
/* Allocate a buffer of reasonable size. Resized when needed */
out_len = in_len*2;
if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL )
return NULL;
out_len_left = out_len;
out_data = (unsigned char *)PyString_AsString(rv);
/*
** We need two macros here to get/put bytes and handle
** end-of-buffer for input and output strings.
*/
#define INBYTE(b) \
do { \
if ( --in_len < 0 ) { \
PyErr_SetString((PYTHON_GLOBALS->binascii_Incomplete), ""); \
Py_DECREF(rv); \
return NULL; \
} \
b = *in_data++; \
} while(0)
#define OUTBYTE(b) \
do { \
if ( --out_len_left < 0 ) { \
_PyString_Resize(&rv, 2*out_len); \
if ( rv == NULL ) return NULL; \
out_data = (unsigned char *)PyString_AsString(rv) \
+ out_len; \
out_len_left = out_len-1; \
out_len = out_len * 2; \
} \
*out_data++ = b; \
} while(0)
/*
** Handle first byte separately (since we have to get angry
** in case of an orphaned RLE code).
*/
INBYTE(in_byte);
if (in_byte == RUNCHAR) {
INBYTE(in_repeat);
if (in_repeat != 0) {
/* Note Error, not Incomplete (which is at the end
** of the string only). This is a programmer error.
*/
PyErr_SetString((PYTHON_GLOBALS->binascii_Error), "Orphaned RLE code at start");
Py_DECREF(rv);
return NULL;
}
OUTBYTE(RUNCHAR);
} else {
OUTBYTE(in_byte);
}
while( in_len > 0 ) {
INBYTE(in_byte);
if (in_byte == RUNCHAR) {
INBYTE(in_repeat);
if ( in_repeat == 0 ) {
/* Just an escaped RUNCHAR value */
OUTBYTE(RUNCHAR);
} else {
/* Pick up value and output a sequence of it */
in_byte = out_data[-1];
while ( --in_repeat > 0 )
OUTBYTE(in_byte);
}
} else {
/* Normal byte */
OUTBYTE(in_byte);
}
}
_PyString_Resize(&rv, (out_data -
(unsigned char *)PyString_AsString(rv)));
return rv;
}
static const char doc_crc_hqx[] =
"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally";
static PyObject *
binascii_crc_hqx(PyObject *self, PyObject *args)
{
unsigned char *bin_data;
unsigned int crc;
int len;
if ( !PyArg_ParseTuple(args, "s#i:crc_hqx", &bin_data, &len, &crc) )
return NULL;
while(len--) {
crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
}
return Py_BuildValue("i", crc);
}
static const char doc_crc32[] =
"(data, oldcrc = 0) -> newcrc. Compute CRC-32 incrementally";
/* Crc - 32 BIT ANSI X3.66 CRC checksum files
Also known as: ISO 3307
**********************************************************************|
* *|
* Demonstration program to compute the 32-bit CRC used as the frame *|
* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
* protocol). The 32-bit FCS was added via the Federal Register, *|
* 1 June 1982, p.23798. I presume but don't know for certain that *|
* this polynomial is or will be included in CCITT V.41, which *|
* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
* errors by a factor of 10^-5 over 16-bit FCS. *|
* *|
**********************************************************************|
Copyright (C) 1986 Gary S. Brown. You may use this program, or
code or tables extracted from it, as desired without restriction.
First, the polynomial itself and its table of feedback terms. The
polynomial is
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+X^0
Note that we take it "backwards" and put the highest-order term in
the lowest-order bit. The X^32 term is "implied"; the LSB is the
X^31 term, etc. The X^0 term (usually shown as "+1") results in
the MSB being 1.
Note that the usual hardware shift register implementation, which
is what we're using (we're merely optimizing it by doing eight-bit
chunks at a time) shifts bits into the lowest-order term. In our
implementation, that means shifting towards the right. Why do we
do it this way? Because the calculated CRC must be transmitted in
order from highest-order term to lowest-order term. UARTs transmit
characters in order from LSB to MSB. By storing the CRC this way,
we hand it to the UART in the order low-byte to high-byte; the UART
sends each low-bit to hight-bit; and the result is transmission bit
by bit from highest- to lowest-order term without requiring any bit
shuffling on our part. Reception works similarly.
The feedback terms table consists of 256, 32-bit entries. Notes:
1. The table can be generated at runtime if desired; code to do so
is shown later. It might not be obvious, but the feedback
terms simply represent the results of eight shift/xor opera-
tions for all combinations of data and CRC register values.
2. The CRC accumulation logic is the same for all CRC polynomials,
be they sixteen or thirty-two bits wide. You simply choose the
appropriate table. Alternatively, because the table can be
generated at runtime, you can start by generating the table for
the polynomial in question and use exactly the same "updcrc",
if your application needn't simultaneously handle two CRC
polynomials. (Note, however, that XMODEM is strange.)
3. For 16-bit CRCs, the table entries need be only 16 bits wide;
of course, 32-bit entries work OK if the high 16 bits are zero.
4. The values must be right-shifted by eight bits by the "updcrc"
logic; the shift must be unsigned (bring in zeroes). On some
hardware you could probably optimize the shift in assembler by
using byte-swap instructions.
********************************************************************/
static const unsigned long crc_32_tab[256] = {
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
0x2d02ef8dUL
};
static PyObject *
binascii_crc32(PyObject *self, PyObject *args)
{ /* By Jim Ahlstrom; All rights transferred to CNRI */
unsigned char *bin_data;
unsigned long crc = 0UL; /* initial value of CRC */
int len;
long result;
if ( !PyArg_ParseTuple(args, "s#|l:crc32", &bin_data, &len, &crc) )
return NULL;
crc = ~ crc;
#if SIZEOF_LONG > 4
/* only want the trailing 32 bits */
crc &= 0xFFFFFFFFUL;
#endif
while (len--)
crc = crc_32_tab[(crc ^ *bin_data++) & 0xffUL] ^ (crc >> 8);
/* Note: (crc >> 8) MUST zero fill on left */
result = (long)(crc ^ 0xFFFFFFFFUL);
#if SIZEOF_LONG > 4
/* Extend the sign bit. This is one way to ensure the result is the
* same across platforms. The other way would be to return an
* unbounded unsigned long, but the evidence suggests that lots of
* code outside this treats the result as if it were a signed 4-byte
* integer.
*/
result |= -(result & (1L << 31));
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?