Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

crc algorithm

72 views
Skip to first unread message

dream...@gmail.com

unread,
Sep 2, 2014, 1:50:17 PM9/2/14
to

Dear all,

I have trouble to implement crc algorithm in python 3.3

c version work perfect. I try to use bytes, int and c_types without any success
can some who help me:

c version:

unsigned short calc_crc(const void *p_dat, int l_dat){
unsigned char *dat_ptr;
int loopc;
unsigned short crc_dat;
unsigned char c_work;

dat_ptr = (unsigned char*)p_dat;
crc_dat = 0x0000;
for (; l_dat > 0; l_dat--)
{
c_work = *(dat_ptr++);
for (loopc = 0; loopc < 8; loopc++)
{
if ((((unsigned char )(crc_dat & 0x0001)) ^ (c_work & 0x01)) == 0x01)
{
crc_dat >>=1 ;
crc_dat ^=0x8408;
} else {
crc_dat >>=1;

}
c_work >>=1;
}
}
return(crc_dat);
}


python tries:

def calc_crc():
crc_dat = c_ushort(0x0001)


data = [0x00,0x00,0x34,0x35,0x38,0x35]
for x in range(len(data)):
pass
c_work = c_ubyte(data[x])
#print(c_work)
for x in range(8):
pass
if (c_ubyte(crc_dat.value & c_ushort(0x0001).value).value ^ c_ubyte(c_work.value & c_ubyte(0x01).value).value) == c_ubyte(0x01):
crc_dat.value >>=1
crc_dat.value ^=0x8408

else:
crc_dat.value >>=1

c_work.value >>=1
print(crc_dat)

print(crc_dat.value)
pass


Peter Otten

unread,
Sep 2, 2014, 2:24:54 PM9/2/14
to pytho...@python.org
dream...@gmail.com wrote:

> I have trouble to implement crc algorithm in python 3.3
>
> c version work perfect. I try to use bytes, int and c_types without any
> success can some who help me:

ctypes is for interfacing with C; don't use it in regular code.

> c version:
>
> unsigned short calc_crc(const void *p_dat, int l_dat){
> unsigned char *dat_ptr;
> int loopc;
> unsigned short crc_dat;
> unsigned char c_work;
>
> dat_ptr = (unsigned char*)p_dat;
> crc_dat = 0x0000;
> for (; l_dat > 0; l_dat--)
> {
> c_work = *(dat_ptr++);
> for (loopc = 0; loopc < 8; loopc++)
> {
> if ((((unsigned char )(crc_dat & 0x0001)) ^
> (c_work & 0x01)) == 0x01)
> {
> crc_dat >>=1 ;
> crc_dat ^=0x8408;
> } else {
> crc_dat >>=1;
>
> }
> c_work >>=1;
> }
> }
> return(crc_dat);
> }

A near-literal translation would be:

def calc_crc(data):
crc = 0
for work in data:
for i in range(8):
if (crc & 1) ^ (work & 1):
crc >>= 1
crc ^= 0x8408
else:
crc >>= 1
work >>= 1
return crc

I don't see any operation where the "unboundedness" of Python's integer type
could be a problem -- but no guarantees.

Chris Kaynor

unread,
Sep 2, 2014, 2:43:52 PM9/2/14
to pytho...@python.org
Also, depending on the use-case, binascii.crc32 might also work fine: https://docs.python.org/2/library/binascii.html#binascii.crc32

import binascii
def calc_crc(data):
    return binascii.crc32(data)

Much simpler.


Chris


On Tue, Sep 2, 2014 at 11:24 AM, Peter Otten <__pe...@web.de> wrote:
dream...@gmail.com wrote:

> I have trouble to implement crc algorithm in python 3.3
>
> c version work  perfect. I try to use bytes, int and c_types without any
> success can some who help me:

ctypes is for interfacing with C; don't use it in regular code.
> c version:
>
> unsigned short calc_crc(const void *p_dat, int l_dat){
>         unsigned char *dat_ptr;
>         int loopc;
>         unsigned short crc_dat;
>         unsigned char c_work;
>
>         dat_ptr = (unsigned char*)p_dat;
>         crc_dat = 0x0000;
>         for (; l_dat > 0; l_dat--)
>         {
>                 c_work = *(dat_ptr++);
>                 for (loopc = 0; loopc < 8; loopc++)
>                 {
>                         if ((((unsigned char )(crc_dat & 0x0001)) ^
>                         (c_work & 0x01)) == 0x01)
>                         {
>                                 crc_dat >>=1 ;
>                                 crc_dat ^=0x8408;
>                         } else {
>                                 crc_dat >>=1;
>
>                         }
>                         c_work >>=1;
>                 }
>         }
>         return(crc_dat);
> }

A near-literal translation would be:

def calc_crc(data):
    crc = 0
    for work in data:
        for i in range(8):
            if (crc & 1) ^ (work & 1):
                crc >>= 1
                crc ^= 0x8408
            else:
                crc >>= 1
            work >>= 1
    return crc

I don't see any operation where the "unboundedness" of Python's integer type
could be a problem -- but no guarantees.

dream...@gmail.com

unread,
Sep 3, 2014, 2:19:07 AM9/3/14
to
this doesn't work

calc_crc(b'\x00\x00\x34\x35\x38\x35')
rsult 0x9f41 , but c function gives us 0x8c40

dream...@gmail.com

unread,
Sep 3, 2014, 2:25:05 AM9/3/14
to
this doesn't work binascii.crc32(data) return 32 bit data , c function crc return 16 bit and it is not standard crc

Peter Otten

unread,
Sep 3, 2014, 3:19:29 AM9/3/14
to pytho...@python.org
Are you sure? I get 0x9f41 with the C version you posted:

$ cat crc.c
#include <stdio.h>

unsigned short calc_crc(const void *p_dat, int l_dat){
unsigned char *dat_ptr;
int loopc;
unsigned short crc_dat;
unsigned char c_work;

dat_ptr = (unsigned char*)p_dat;
crc_dat = 0x0000;
for (; l_dat > 0; l_dat--)
{
c_work = *(dat_ptr++);
for (loopc = 0; loopc < 8; loopc++)
{
if ((((unsigned char )(crc_dat & 0x0001)) ^ (c_work
& 0x01)) == 0x01)
{
crc_dat >>=1 ;
crc_dat ^=0x8408;
} else {
crc_dat >>=1;

}
c_work >>=1;
}
}
return(crc_dat);
}

main()
{
unsigned char data[] = "\x00\x00\x34\x35\x38\x35";
unsigned short crc = calc_crc(data, 6);
printf("%x\n", crc);
}
$ gcc crc.c
$ ./a.out
9f41


Mark Lawrence

unread,
Sep 3, 2014, 3:22:34 AM9/3/14
to pytho...@python.org
On 03/09/2014 07:19, dream...@gmail.com wrote:

Would you please access this list via
https://mail.python.org/mailman/listinfo/python-list or read and action
this https://wiki.python.org/moin/GoogleGroupsPython to prevent us
seeing double line spacing and single line paragraphs, thanks.

--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

dream...@gmail.com

unread,
Sep 3, 2014, 4:43:37 AM9/3/14
to
int main(int argc, char const *argv[])
{
unsigned short rez;
unsigned char a[]={0x30,0x30,0x34,0x35,0x38,0x35};

unsigned short val;

rez=calc_crc(a,(int)sizeof(a));
printf("%#hx\n",rez );

return 0;
}

dream...@gmail.com

unread,
Sep 3, 2014, 4:46:34 AM9/3/14
to
int main(int argc, char const *argv[])
{
unsigned short rez;
unsigned char a[]={0x30,0x30,0x34,0x35,0x38,0x35};

unsigned short val;

rez=calc_crc(a,(int)sizeof(a));
printf("%#hx\n",rez );

return 0;
}

o$ gcc main.c
o$ ./a.out
0x8c40

Peter Otten

unread,
Sep 3, 2014, 5:00:10 AM9/3/14
to pytho...@python.org
dream...@gmail.com wrote:

> calc_crc(b'\x00\x00\x34\x35\x38\x35')

> unsigned char a[]={0x30,0x30,0x34,0x35,0x38,0x35};

The first two bytes differ; you made an error on the input.

dream...@gmail.com

unread,
Sep 3, 2014, 7:00:06 AM9/3/14
to
Dear Peter, my apologies it's my mistake. Thank you for help. Problem solved.
Message has been deleted
0 new messages