Coder Social home page Coder Social logo

pycrc's People

Contributors

andre-hartmann avatar ashelly avatar ftheile avatar intgr avatar jeffwidman avatar kripton avatar smurfix avatar tpircher-zz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pycrc's Issues

example main program, read from stdin

Nice tool ! I needed to implement Zip CRC and it worked. Thanks

However, I found the generated main function not so useful.
I propose :

#include <stdio.h>
#include <string.h>
#include "crc.h"

#define BLOCK_SIZE 16384

int main(void) {
    char* buffer[BLOCK_SIZE];
    crc_t crc = crc_init();
    for(;;) {
        size_t bytes = fread(buffer,  sizeof(char),BLOCK_SIZE,stdin);
        crc = crc_update(crc, buffer, bytes);
        if (bytes < BLOCK_SIZE)
            if (feof(stdin))
                break;
    }
    crc = crc_finalize(crc);
    printf("%lx", (unsigned long)crc);
    return 0;
}

which prints crc of stdin to stdout.

Reflection of xor-in wrong for 32-bit CRC?

The "normal" crc32 (in python available in zlib or binascii) can do continuation of a crc, i.e. (python3):

>>> from zlib import crc32
>>> crc32(b'12345678')
2598427311
>>> crc32(b'12345678', 2598427311)
1808553911
>>> crc32(b'1234567812345678')
1808553911

pycrc doesn't seem to get this right (I've installed the pycrc.py as pycrc in my path, the prompt is designed to allow cutting/pasting the whole line):

: %; pycrc --version
pycrc v0.9.2

: %; pycrc --width=32 --poly=0x04c11db7 --xor-in=0 --xor-out=0 \
        --reflect-in=1 --reflect-out=1 --check-hexstring 12345678
0x6b4dd184
: %; pycrc --width=32 --poly=0x04c11db7 --xor-in=0x6b4dd184 --xor-out=0 \
        --reflect-in=1 --reflect-out=1 --check-hexstring 12345678
0x3ab64c61
: %; pycrc --width=32 --poly=0x04c11db7 --xor-in=0 --xor-out=0
        --reflect-in=1 --reflect-out=1 --check-hexstring 1234567812345678
0x1a8a2677

If I reverse the output value 0x6b4dd184 before using it in the second call above it works:

: %; ./rev 0x6b4dd184
0x218bb2d6
: %; pycrc --width=32 --poly=0x04c11db7 --xor-in=0x218bb2d6 --xor-out=0 \
        --reflect-in=1 --reflect-out=1 --check-hexstring 12345678
0x1a8a2677

So it looks like pycrc should reflect the xor-in value before xoring it into the register for reflected algos.
Note that I'm not sure why pycrc gets it wrong for 32 bit but seems to get it right for crc16, there is the 16-bit model 'crc-16-ccitt' which has an asymmetric xor-in value of 0x1d0f. This produces a check-value consistent with other crc implementation of the same algo (e.g. reveng which names it CRC-16/SPI-FUJITSU). And continuation works, too (the algo has a zero xor-out, so we don't need to compensate):

: %; pycrc --width=16 --poly=0x1021 --xor-in=0x1d0f --xor-out=0 \
           --reflect-in=0 --reflect-out=0 --check-string=1234567812345678
0x5b57
: %; pycrc --width=16 --poly=0x1021 --xor-in=0x1d0f --xor-out=0 \
           --reflect-in=0 --reflect-out=0 --check-string=12345678
0x712c
: %; pycrc --width=16 --poly=0x1021 --xor-in=0x712c --xor-out=0 \
           --reflect-in=0 --reflect-out=0 --check-string=12345678
0x5b57

Any ideas?

Problem with 0x00

So I generated the C source code using the following parameters.
python pycrc.py --width 8 --algorithm tbl --poly 0x31 --reflect-in true --reflect-out true --xor-in 0x10 --xor-out 0xF7 --generate c -o crc.c

I'm using http://www.sunshine2k.de/coding/javascript/crc/crc_js.html to confirm my output.
And I noticed that using 0x00 gives me a different value on the C source code than on the JS calculator.
With this parameters 0x00 should output 0x35 but on the C code it's outputting 0xFF.
Also note that using any chain that contains 0x00 also gives a different output.
Ex. {0xFE, 0x61, 0x01, 0x00, 0x16, 0x02, 0x00, 0x14, 0x8C} should be 0x24 but it's 0x6b on the C code.
Is there something I can do to make the C code match the JS calculator?

Slice-by-8 CRC16: Problem with type of d1,d2 in generated code

When generating code for this:

  • Generated on Wed Feb 19 00:52:04 2020
  • by pycrc v0.9.2, https://pycrc.org
  • using the configuration:
    • Width = 16
    • Poly = 0x8005
    • XorIn = 0x0000
    • ReflectIn = True
    • XorOut = 0x0000
    • ReflectOut = True
    • Algorithm = table-driven
    • SliceBy = 8

the generated code contains this:
typedef uint_fast16_t crc_t;

If uint_fast16_t is actually 32 bits, this will make my tables twice as big as they need to be, so I substituted uint16_t for crc_t, but this is also a problem: In the following generated code (LE version shown)
crc_t d1 = *d32++ ^ crc;
crc_t d2 = *d32++;
the type of d1 and d2 should NOT be 16-bits. I changed the types here to uint32_t and everything seems to work fine.

CRC-32C incorrect

I'm trying to use code generated by ./pycrc.py --model crc-32c --algorithm table-driven --generate c / ./pycrc.py --model crc-32c --algorithm table-driven --generate h to generate snappy-framed data, but the checksums don't match what other implementations expect.

Appendix B.4 of RFC 3720 includes some test vectors, so I threw together a quick program to verify pycrc's implementation and it fails:

#include "crc32.h"
#include <assert.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
  const uint8_t test_vectors[][32] = {
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
      0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
      0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
    { 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
      0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
      0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
      0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }
  };

  assert (0xaa36918a == crc_finalize (crc_update(crc_init (), test_vectors[0], sizeof(test_vectors[0]))));
  assert (0x43aba862 == crc_finalize (crc_update(crc_init (), test_vectors[1], sizeof(test_vectors[1]))));
  assert (0x4e79dd46 == crc_finalize (crc_update(crc_init (), test_vectors[2], sizeof(test_vectors[2]))));
  assert (0x5cdb3f11 == crc_finalize (crc_update(crc_init (), test_vectors[3], sizeof(test_vectors[3]))));

  return 0;
}

error: different checksums!

Due to hardware constraints, attempting to generate an 8-bit CRC using a 16-bit CRC.
pycrc gives different answers for its separate algorithms.

> python --version
Python 2.7.10
>python pycrc.py --width=8 --poly=0x105 --reflect-in=False --xor-in=0xfe --reflect-out=False --xor-out=0x00
0x91
> python pycrc.py --width=16 --poly=0x10500 --reflect-in=False --xor-in=0xfe00 --reflect-out=False --xor-out=0x00
pycrc.py: error: different checksums!
       bit-by-bit:        0x100
       bit-by-bit-fast:   0x9100
       table_driven:      0x9100

crc-24q used with RTCMv3

Qualcomm CRC-24Q as used with RTCMv3. Similar to the other crc-24 but with xor_in = 0.

models.append({
    'name':         'crc-24q',
    'width':         24,
    'poly':          0x864cfb,
    'reflect_in':    False,
    'xor_in':        0x0,
    'reflect_out':   False,
    'xor_out':       0x0,
    'check':         0xcde703,
})

Generated code was verified on real RTCM data, 'check' was produced by --check-string "123456789". Checking with another RTCMv3 string should show this, matching the checksum on the wire 0xa8f72a:

python3 pycrc.py --width=24 --poly=0x864CFB --reflect-in=false --xor-in=0 --reflect-out=false --xor-out=0 --check-hexstring "d300084ce0008a00000000"
0xa8f72a

Is it return the wrong poly?

When I run this:
./pycrc.py --verbose --width 10 --poly 0x633 --reflect-in False --xor-in 0 --reflect-out False --xor-out 0 --algorithm table-driven --generate c -o crc10.c
it gives this:
Width = 10
Poly = 0x233
ReflectIn = False
XorIn = 0x000
ReflectOut = False
XorOut = 0x000
Algorithm = table-driven

The poly is not the one I input, but the crc10.c is same when poly is 0x633 and 0x233, and the same in the c code。
I am not read the code deeply, but I've tried other numbers, and I find, it seems that it missed the leading "1" more than 10 bits. But I think this is a bug, the poly output should be just the one which is from input.

Code generation use different algorithm for reflected

When generating code for a "reflected" CRC, a function is used to reflect each input byte. This is inefficient—it would be preferable to use an alternative core CRC algorithm that is a "reflected" algorithm. See Chapter 11 "Reflected" Table-Driven Implementations of A Painless Guide to CRC Error Detection Algorithms by Ross Williams. That describes a reflected table-driven algorithm; there would similarly be a reflected bit-by-bit algorithm.

speed

I'ld be interested in the actual speed of the generated compiled code. Guess quite some other people looking at this project might also be wondering about this.

It would be nice if one could generate a main() function that computes a crc over a specific, given amount of data and measures the time needed for that. Like 1MB of 0x42 or so.

So one could easily compare the different crc algorithms implemented by your code to existing crc implementations to find out what's fastest.

In my case, I am esp. interested in:

  • a function fully compatible to python3's zlib.crc32, but (significantly) faster
  • any function somehow comparable to crc32, but significantly faster

Checksum backwards?

The crc-16-modbus model is backwards for example it says: "0xA762" when is "0x62A7".

EDIT: My mistake! it works fine.

Specification of CRC-16/CCITT initial value

There is some confusion about the "correct" initial value of the 16-bit CCITT CRC. See CRC-CCITT -- 16-bit (other source) which explains it.

It has to do with the question of "augmented" zero bits at the end of the message, and an algorithm that can avoid the need for it, but needs a modification to the initial value. See Chapter 10, "A Slightly Mangled Table-Driven Implementation", of A Painless Guide to CRC Error Detection Algorithms for an explanation.

In short, perhaps pycrc's ccitt model should have an --xor-in initial value of 0x1D0F instead of 0xFFFF.

See also:

Use "const void*" instead of "const char*" for crc_update()

When using pycrc with C++ code you need to use a lot of reinterpret_cast<const unsigned char*>(...) when calling crc_update() with anything other than unsigned char, because C++ doesn't allow implicit conversion between such types. The only implicit conversion that is allowed is "anything" -> "const void*", so I'd propose to change prototype of crc_update() to:

crc_t crc_update(crc_t crc, const void *data, size_t data_len);

speed improvement using SSE4 crc32 cpu instruction?

There is special support for crc computation in intel/AMD CPUs since quite some years:

http://www.drdobbs.com/parallel/fast-parallelized-crc-computation-using/229401411

https://en.wikipedia.org/wiki/SSE4#Supporting_CPUs

The drdobbs article says that this yields performance of about 1.17 cycles per 64bits word (for a measurement done with a loop, repeatedly computing over a small amount of data, so I guess one can assume they sit in L1 or L2 cache of cpu).

At 2.4GHz, this could mean up to 16GB/s (or whatever your RAM bandwidth is limiting this value to).

Binary files with Python 2.7

My binary file starts with 0xff - and when I run:

$ python2.7 ~/git/pycrc/pycrc.py --model=crc-16 --check-file forthboot.bin --xor-in=0xffff --reflect-out=0 --xor-out=0xffff
Traceback (most recent call last):
  File "/Users/jamesb/git/pycrc/pycrc.py", line 269, in <module>
    sys.exit(main())
  File "/Users/jamesb/git/pycrc/pycrc.py", line 240, in main
    crc = check_file(opt)
  File "/Users/jamesb/git/pycrc/pycrc.py", line 198, in check_file
    register = crc_file_update(alg, register, check_bytes)
  File "/Users/jamesb/git/pycrc/pycrc.py", line 152, in crc_file_update
    check_bytes = bytearray(check_bytes, 'utf-8')

Works fine with python3.5

broken on python 3.10 ?

Traceback (most recent call last):
  File "/usr/bin/pycrc", line 26, in <module>
    from pycrc.main import main
  File "/usr/lib/python3.10/site-packages/pycrc/main.py", line 46, in <module>
    import pycrc.codegen as cg
  File "/usr/lib/python3.10/site-packages/pycrc/codegen.py", line 37, in <module>
    import pycrc.symtable
  File "/usr/lib/python3.10/site-packages/pycrc/symtable.py", line 49, in <module>
    class SymbolTable(collections.MutableMapping):
AttributeError: module 'collections' has no attribute 'MutableMapping'

Looks like collections.MutableMapping was deprecated at some point ?

[wishlist] aligned access for table driven

Thanks for pycrc!

For table driven algorithms with --table-idx-width greater than 1, it would be nice to generate code that ensures aligned access.

Currently, any trailing unaligned bytes are handled individually (i.e. anything after the Remaining bytes with the standard algorithm comment), but it would be great to handle leading unaligned bytes individually as well, to ensure that the main loop is using aligned loads.

Big/little endian support

Hi
Is it any way to generate c code (or two versions of code) which will support both big and little endian CPUs?
Kris

Addition to Frequently Asked Questions, Linux-specific : Error ": No such file or directory" when trying to run pycrc.py on Linux

Please consider adding this verbiage to the Frequently Asked Questions list for pycrc :

Problem :
Error ": No such file or directory" when trying to run pycrc.py on Linux

Solution :
After extracting pycrc-0.8.3.zip with the linux 'unzip' command, run the command "dos2unix /path/to/pycrc-0.8.3/pycrc.py" to convert the file from MS-DOS format to Unix format.

Failure to do this can result in the error ": No such file or directory" when running the command "pycrc.py --help"

Thank you for your attention on this matter.

Do not get table output

I do not get any code beside the header comment when I call it as follows
./pycrc.py --width=8 --poly=0x07 --xor-in=0 --xor-out=0x55 --reflect-in=false --reflect-out=False --table-idx-width=4 --algorithm=table-driven --generate=table

I ecpected some kind of hex number sequence to be included in my static table (at least v0.7.8 worked this way).

Wish: Separate crc initialization from feeding

Currently the Crc class in algorithms.py can only feed a single string into algo. This should be changed to separate initialization (xor-in), feeding and finalization (xor-out). This has the following advantages:

  • The File input can use the same mechanism, the current file-feeding implementation is sort of a workaround
  • We can run through the algorithm one feed-unit at a time. This is nice, e.g., when searching for a given initial state when running a CRC backwards (with reflected poly and reflected input) until a start-state is reached
  • We could feed bit-wise for the bitwise variants

To make this work I'd separate the single Crc class into three classes, each one implementing the given variant, e.g. CrcBitByBit, CrcTableDriven, ... because the feeding is probably not compatible across the variants.

This would also allow bitwise feeding for the bitwise algos: My use-case here is finding the number of excess bits at the end of a message described in the section "Clearing Up some Puzzles" of Gregory Ewings "Reverse-.Engineering a CRC Algorithm": Here we're running a CRC with only the polynomial known over a XOR of two different messages that differ by only one bit (Greg calls this a difference-message). This is used to discover how far to go (over how much data the original CRC was computed, if it included additional data after the contents we know about). The Algo is initialized with the poly in the register and run until the known CRC is reached (the CRC of two XORed messages is the XOR of both CRC values)
If the 1-bit difference is not on a byte boundary this fails. So we need a way to bitwise feed the algorithm (with zeros in this use-case).

Do we have a regression test? In that case I'd do a stab at this and propose a code-change.

Model CRC-5 generates a left shift by 8 bits which is too big for data type

When using the following command line:

/pycrc.py --model crc-5 --algorithm table-driven --std=c89 --generate c -o source.c

a source.c is generated with following crc_update:

 crc_t crc_update(crc_t crc, const unsigned char *data, size_t data_len)
 {
     unsigned int tbl_idx;

     while (data_len--) {
         tbl_idx = ((crc >> 3) ^ *data) & 0xff;
         crc = (crc_table[tbl_idx] ^ (crc >> 8)) & (0x1f << 3);

         data++;
     }
     return crc & (0x1f << 3);

with crc_t typedef'ed to unsigned char.

This means that the crc >> 8 is always 0. Is this intended?

pycrc.py --version
pycrc v0.8.2

Generation of C file

Hi,

I calculated CRC-16/X-25. and Now I want to generate a C-file for that. I am writing the following command.

pycrc.py --model x-25 --generate c -o crc

//crc is the file name
And I am getting the following error:

pycrc: error: select an algorithm to be used in the generated file

I am not able to decode this error. Can you please help me with it. Thank you.

"pycrc" != "PyCRC" but same url used in python package index

Hello,
I was using PyCRC in my project (https://libraries.io/pypi/PyCRC / https://github.com/alexbutirskiy/PyCRC, which is not maintained any more and has nothing to do with https://github.com/tpircher/pycrc) and my nightly builds started failing, because the python package index removed "PyCRC 1.21" and added "pycrc version 0.9.2" instead (https://pypi.org/project/pycrc/#history shows the release was done on January 24), therefore I started getting those error messages:

ERROR: Could not find a version that satisfies the requirement PyCRC==1.21 (from -r requirements.txt (line 3)) (from versions: 0.9.2)
ERROR: No matching distribution found for PyCRC==1.21 (from -r requirements.txt (line 3))

I just wanted to document the issue there in case it affects other people. It is quite confusing that the python package index just replaced one package with another even though they are not related, and kept the same package name with a different case, knowing that pip is case insensitive.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.