18d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
28d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Low level CRC functions for use by crcmod.  This version is the C
38d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// implementation that corresponds to the Python module _crcfunpy.  This module
48d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// will be used by crcmod if it is built for the target platform.  Otherwise,
58d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// the Python module is used.
68d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//
78d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Copyright (c) 2010  Raymond L. Buvel
88d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Copyright (c) 2010  Craig McQueen
98d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//
108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Permission is hereby granted, free of charge, to any person obtaining a copy
118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// of this software and associated documentation files (the "Software"), to
128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// deal in the Software without restriction, including without limitation the
138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// sell copies of the Software, and to permit persons to whom the Software is
158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// furnished to do so, subject to the following conditions:
168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//
178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// The above copyright notice and this permission notice shall be included in
188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// all copies or substantial portions of the Software.
198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//
208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// IN THE SOFTWARE.
278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define PY_SSIZE_T_CLEAN
308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <Python.h>
318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Note: the type declarations are set up to work on 32-bit and 64-bit
338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// platforms using the GNU C compiler.  They may need to be adjusted for other
348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// platforms.
358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Define a few types to make it easier to port to other platforms.
378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoitypedef unsigned char UINT8;
388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoitypedef unsigned short UINT16;
398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoitypedef unsigned int UINT32;
408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoitypedef unsigned long long UINT64;
418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Define some macros for the data format strings.  The INPUT strings are for
438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// decoding the input parameters to the function which are (data, crc, table).
448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define INPUT8 "OBs#"
468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define INPUT16 "OHs#"
478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define INPUT32 "OIs#"
488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define INPUT64 "OKs#"
498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// The following macro is taken from hashlib.h in the Python 3.1 code,
518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// providing "Common code for use by all hashlib related modules".
528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Given a PyObject* obj, fill in the Py_buffer* viewp with the result
548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// of PyObject_GetBuffer.  Sets an exception and issues a return NULL
558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// on any errors.
568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) do { \
578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        if (PyUnicode_Check((obj))) { \
588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            PyErr_SetString(PyExc_TypeError, \
598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            "Unicode-objects must be encoded before calculating a CRC");\
608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            return NULL; \
618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        } \
628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        if (!PyObject_CheckBuffer((obj))) { \
638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            PyErr_SetString(PyExc_TypeError, \
648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            "object supporting the buffer API required"); \
658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            return NULL; \
668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        } \
678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \
688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            return NULL; \
698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        } \
708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        if ((viewp)->ndim > 1) { \
718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            PyErr_SetString(PyExc_BufferError, \
728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            "Buffer must be single dimension"); \
738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            PyBuffer_Release((viewp)); \
748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi            return NULL; \
758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        } \
768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    } while(0);
778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Define some macros that extract the specified byte from an integral value in
798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// what should be a platform independent manner.
808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define BYTE0(x) ((UINT8)(x))
818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define BYTE1(x) ((UINT8)((x) >> 8))
828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define BYTE2(x) ((UINT8)((x) >> 16))
838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define BYTE3(x) ((UINT8)((x) >> 24))
848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#define BYTE7(x) ((UINT8)((x) >> 56))
858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 8-bit crc over the input data.
888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 8-bit table corresponding to the generator
928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc8(PyObject* self, PyObject* args)
988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
1008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
1018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8 crc;
1028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
1038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
1048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* table;
1058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
1068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT8, &obj, &crc,
1088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
1098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
1108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
1118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
1128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256)
1148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
1158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
1168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
1178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
1188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
1208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
1218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
1228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
1248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
1258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ crc];
1268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
1278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
1288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
1308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromLong((long)crc);
1328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
1338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
1358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 8-bit crc over the input data.  The data stream is bit reversed
1368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// during the computation.
1378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
1388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
1398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
1408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 8-bit table corresponding to the generator
1418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
1428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
1438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
1448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
1468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc8r(PyObject* self, PyObject* args)
1478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
1488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
1498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
1508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8 crc;
1518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
1528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
1538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* table;
1548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
1558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT8, &obj, &crc,
1578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
1588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
1598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
1608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
1618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256)
1638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
1648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
1658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
1668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
1678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
1698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
1708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
1718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
1738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
1748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ crc];
1758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
1768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
1778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
1798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromLong((long)crc);
1818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
1828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
1848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 16-bit crc over the input data.
1858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
1868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
1878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
1888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 16-bit table corresponding to the generator
1898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
1908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
1918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
1928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
1948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc16(PyObject* self, PyObject* args)
1958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
1968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
1978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
1988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT16 crc;
1998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
2008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
2018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT16* table;
2028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
2038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT16, &obj, &crc,
2058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
2068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
2078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
2088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
2098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256*2)
2118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
2128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
2138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
2148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
2158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
2178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
2188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
2198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
2218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
2228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ BYTE1(crc)] ^ (crc << 8);
2238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
2248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
2258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
2278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromLong((long)crc);
2298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
2308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
2328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 16-bit crc over the input data.  The data stream is bit reversed
2338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// during the computation.
2348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
2358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
2368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
2378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 16-bit table corresponding to the generator
2388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
2398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
2408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
2418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
2438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc16r(PyObject* self, PyObject* args)
2448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
2458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
2468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
2478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT16 crc;
2488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
2498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
2508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT16* table;
2518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
2528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT16, &obj, &crc,
2548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
2558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
2568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
2578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
2588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256*2)
2608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
2618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
2628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
2638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
2648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
2668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
2678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
2688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
2708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
2718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ BYTE0(crc)] ^ (crc >> 8);
2728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
2738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
2748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
2768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromLong((long)crc);
2788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
2798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
2818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 24-bit crc over the input data.
2828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
2838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
2848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
2858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 24-bit table corresponding to the generator
2868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
2878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
2888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
2898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
2908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
2918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc24(PyObject* self, PyObject* args)
2928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
2938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
2948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
2958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT32 crc;
2968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
2978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
2988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT32* table;
2998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
3008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT32, &obj, &crc,
3028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
3038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
3048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
3058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
3068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256*4)
3088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
3098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
3108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
3118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
3128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
3148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
3158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
3168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
3188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
3198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ BYTE2(crc)] ^ (crc << 8);
3208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
3218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
3228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
3248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromLong((long)(crc & 0xFFFFFFU));
3268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
3278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
3298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 24-bit crc over the input data.  The data stream is bit reversed
3308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// during the computation.
3318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
3328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
3338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
3348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 24-bit table corresponding to the generator
3358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
3368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
3378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
3388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
3408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc24r(PyObject* self, PyObject* args)
3418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
3428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
3438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
3448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT32 crc;
3458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
3468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
3478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT32* table;
3488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
3498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT32, &obj, &crc,
3518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
3528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
3538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
3548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
3558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256*4)
3578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
3588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
3598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
3608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
3618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
3638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
3648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
3658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    crc = crc & 0xFFFFFFU;
3678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
3688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
3698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ BYTE0(crc)] ^ (crc >> 8);
3708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
3718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
3728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
3748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromLong((long)crc);
3768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
3778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
3798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 32-bit crc over the input data.
3808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
3818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
3828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
3838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 32-bit table corresponding to the generator
3848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
3858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
3868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
3878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
3898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc32(PyObject* self, PyObject* args)
3908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
3918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
3928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
3938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT32 crc;
3948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
3958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
3968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT32* table;
3978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
3988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
3998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT32, &obj, &crc,
4008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
4018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
4028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
4038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
4048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256*4)
4068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
4078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
4088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
4098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
4108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
4128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
4138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
4148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
4168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
4178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ BYTE3(crc)] ^ (crc << 8);
4188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
4198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
4208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
4228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromUnsignedLong(crc);
4248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
4258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
4278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 32-bit crc over the input data.  The data stream is bit reversed
4288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// during the computation.
4298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
4308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
4318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
4328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 32-bit table corresponding to the generator
4338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
4348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
4358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
4368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
4388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc32r(PyObject* self, PyObject* args)
4398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
4408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
4418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
4428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT32 crc;
4438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
4448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
4458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT32* table;
4468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
4478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT32, &obj, &crc,
4498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
4508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
4518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
4528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
4538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256*4)
4558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
4568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
4578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
4588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
4598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
4618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
4628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
4638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
4658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
4668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ BYTE0(crc)] ^ (crc >> 8);
4678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
4688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
4698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
4718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromUnsignedLong(crc);
4738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
4748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
4768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 64-bit crc over the input data.
4778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
4788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
4798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
4808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 64-bit table corresponding to the generator
4818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
4828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
4838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
4848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
4868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc64(PyObject* self, PyObject* args)
4878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
4888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
4898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
4908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT64 crc;
4918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
4928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
4938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT64* table;
4948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
4958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
4968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT64, &obj, &crc,
4978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
4988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
4998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
5008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
5018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256*8)
5038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
5048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
5058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
5068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
5078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
5098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
5108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
5118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
5138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
5148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ BYTE7(crc)] ^ (crc << 8);
5158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
5168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
5178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
5198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromUnsignedLongLong(crc);
5218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
5228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
5248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Compute a 64-bit crc over the input data.  The data stream is bit reversed
5258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// during the computation.
5268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Inputs:
5278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   data - string containing the data
5288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the initial crc
5298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   table - string containing the 64-bit table corresponding to the generator
5308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//           polynomial.
5318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi// Returns:
5328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//   crc - unsigned integer containing the resulting crc
5338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyObject*
5358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_crc64r(PyObject* self, PyObject* args)
5368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
5378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyObject *obj;
5388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_buffer buf;
5398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT64 crc;
5408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT8* data;
5418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t dataLen;
5428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    UINT64* table;
5438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    Py_ssize_t tableLen;
5448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (!PyArg_ParseTuple(args, INPUT64, &obj, &crc,
5468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                            &table, &tableLen))
5478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
5488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
5498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
5508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if (tableLen != 256*8)
5528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
5538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        PyErr_SetString(PyExc_ValueError, "invalid CRC table");
5548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        return NULL;
5558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
5568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
5588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    data = buf.buf;
5598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    dataLen = buf.len;
5608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    while (dataLen--)
5628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
5638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        crc = table[*data ^ BYTE0(crc)] ^ (crc >> 8);
5648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        data++;
5658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
5668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    PyBuffer_Release(&buf);
5688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyLong_FromUnsignedLongLong(crc);
5708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
5718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
5738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic PyMethodDef methodTable[] = {
5748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc8", _crc8, METH_VARARGS},
5758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc8r", _crc8r, METH_VARARGS},
5768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc16", _crc16, METH_VARARGS},
5778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc16r", _crc16r, METH_VARARGS},
5788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc24", _crc24, METH_VARARGS},
5798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc24r", _crc24r, METH_VARARGS},
5808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc32", _crc32, METH_VARARGS},
5818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc32r", _crc32r, METH_VARARGS},
5828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc64", _crc64, METH_VARARGS},
5838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{"_crc64r", _crc64r, METH_VARARGS},
5848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{NULL, NULL}
5858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi};
5868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
5888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic struct PyModuleDef moduleDef = {
5898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi   PyModuleDef_HEAD_INIT,
5908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi   "_crcfunext",  // name of module
5918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi   NULL,          // module documentation, may be NULL
5928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi   -1,            // size of per-interpreter state of the module,
5938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi                  // or -1 if the module keeps state in global variables.
5948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi   methodTable
5958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi};
5968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
5978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi//-----------------------------------------------------------------------------
5988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiPyMODINIT_FUNC
5998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiPyInit__crcfunext(void)
6008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi{
6018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    if ((sizeof(UINT8) != 1) || (sizeof(UINT16) != 2) ||
6028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        (sizeof(UINT32) != 4) || (sizeof(UINT64) != 8))
6038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {
6048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi        Py_FatalError("crcfunext: One of the data types is invalid");
6058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }
6068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
6078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    return PyModule_Create(&moduleDef);
6088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi}
6098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
610