3

I have the below code which I am trying to convert to Java.

WORD ComputeCRC16(BYTE *data, DWORD data_length)
{
   BYTE *ptr;
   BYTEWORD retval;

    /* Initialize the CRC */
    retval.w = 0xFFFF;

   /* Iterate through the data */
   for (ptr=data; ptr<data+data_length; ptr++)
   {
      // retval.w = IterateCRC16(ptr, retval);
      retval.w = retval.b.hi ^ (ccittrev_tbl[retval.b.lo ^ *ptr]);

   }

   /* Finalize the CRC */
   retval.w = ~retval.w;

   /* Done. */
   return retval.w;
}

What does the below line mean?

retval.w = retval.b.hi ^ (ccittrev_tbl[retval.b.lo ^ *ptr]);

retval should be an int if i convert to Java right? If then how can it have a memeber called "w" ? Please advice how I can convert the above line to Java?

I'm editing the question to post this part I had missed.

typedef union
{
  WORD  w;
  struct
  {
     BYTE  lo,
        hi;
   } b;
} BYTEWORD;         

Edited after suggestions :

static int calculate_crc(byte[] data) {
     int retval_w = 0x0000;
     int ccittrev_tbl[] = {
                0x0000,  0xC0C1,  0xC181,  0x0140,  0xC301,  0x03C0,  0x0280,  0xC241,
                0xC601,  0x06C0,  0x0780,  0xC741,  0x0500,  0xC5C1,  0xC481,  0x0440,
                0xCC01,  0x0CC0,  0x0D80,  0xCD41,  0x0F00,  0xCFC1,  0xCE81,  0x0E40,
                0x0A00,  0xCAC1,  0xCB81,  0x0B40,  0xC901,  0x09C0,  0x0880,  0xC841,
                0xD801,  0x18C0,  0x1980,  0xD941,  0x1B00,  0xDBC1,  0xDA81,  0x1A40,
                0x1E00,  0xDEC1,  0xDF81,  0x1F40,  0xDD01,  0x1DC0,  0x1C80,  0xDC41,
                0x1400,  0xD4C1,  0xD581,  0x1540,  0xD701,  0x17C0,  0x1680,  0xD641,
                0xD201,  0x12C0,  0x1380,  0xD341,  0x1100,  0xD1C1,  0xD081,  0x1040,
                0xF001,  0x30C0,  0x3180,  0xF141,  0x3300,  0xF3C1,  0xF281,  0x3240,
                0x3600,  0xF6C1,  0xF781,  0x3740,  0xF501,  0x35C0,  0x3480,  0xF441,
                0x3C00,  0xFCC1,  0xFD81,  0x3D40,  0xFF01,  0x3FC0,  0x3E80,  0xFE41,
                0xFA01,  0x3AC0,  0x3B80,  0xFB41,  0x3900,  0xF9C1,  0xF881,  0x3840,
                0x2800,  0xE8C1,  0xE981,  0x2940,  0xEB01,  0x2BC0,  0x2A80,  0xEA41,
                0xEE01,  0x2EC0,  0x2F80,  0xEF41,  0x2D00,  0xEDC1,  0xEC81,  0x2C40,
                0xE401,  0x24C0,  0x2580,  0xE541,  0x2700,  0xE7C1,  0xE681,  0x2640,
                0x2200,  0xE2C1,  0xE381,  0x2340,  0xE101,  0x21C0,  0x2080,  0xE041,
                0xA001,  0x60C0,  0x6180,  0xA141,  0x6300,  0xA3C1,  0xA281,  0x6240,
                0x6600,  0xA6C1,  0xA781,  0x6740,  0xA501,  0x65C0,  0x6480,  0xA441,
                0x6C00,  0xACC1,  0xAD81,  0x6D40,  0xAF01,  0x6FC0,  0x6E80,  0xAE41,
                0xAA01,  0x6AC0,  0x6B80,  0xAB41,  0x6900,  0xA9C1,  0xA881,  0x6840,
                0x7800,  0xB8C1,  0xB981,  0x7940,  0xBB01,  0x7BC0,  0x7A80,  0xBA41,
                0xBE01,  0x7EC0,  0x7F80,  0xBF41,  0x7D00,  0xBDC1,  0xBC81,  0x7C40,
                0xB401,  0x74C0,  0x7580,  0xB541,  0x7700,  0xB7C1,  0xB681,  0x7640,
                0x7200,  0xB2C1,  0xB381,  0x7340,  0xB101,  0x71C0,  0x7080,  0xB041,
                0x5000,  0x90C1,  0x9181,  0x5140,  0x9301,  0x53C0,  0x5280,  0x9241,
                0x9601,  0x56C0,  0x5780,  0x9741,  0x5500,  0x95C1,  0x9481,  0x5440,
                0x9C01,  0x5CC0,  0x5D80,  0x9D41,  0x5F00,  0x9FC1,  0x9E81,  0x5E40,
                0x5A00,  0x9AC1,  0x9B81,  0x5B40,  0x9901,  0x59C0,  0x5880,  0x9841,
                0x8801,  0x48C0,  0x4980,  0x8941,  0x4B00,  0x8BC1,  0x8A81,  0x4A40,
                0x4E00,  0x8EC1,  0x8F81,  0x4F40,  0x8D01,  0x4DC0,  0x4C80,  0x8C41,
                0x4400,  0x84C1,  0x8581,  0x4540,  0x8701,  0x47C0,  0x4680,  0x8641,
                0x8201,  0x42C0,  0x4380,  0x8341,  0x4100,  0x81C1,  0x8081,  0x4040
            };

        for (byte b : data) {
            retval_w = ((retval_w>>8)&0xff) ^ (ccittrev_tbl[(retval_w&0xff) ^ b]);

        }
}
AnOldSoul
  • 4,017
  • 12
  • 57
  • 118
  • 1
    So what's the [C++] tag for? – Arc676 Dec 21 '15 at 07:34
  • 1
    It's bitwise XOR operator http://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_logic_operators – Denis Dec 21 '15 at 07:35
  • Does Java even have bitwise operators? – Lundin Dec 21 '15 at 07:37
  • Guys I think this is a c++ code not java one. he wants to convert it to java – Humam Helfawi Dec 21 '15 at 07:37
  • @user3514538 I was asking about the "retval.b.hi" line. If I convert retval to java it should be an int. Then how would I write retval.b.hi? – AnOldSoul Dec 21 '15 at 07:38
  • @Arc676 I believe these data types should be applicable to C++ as well. Sorry if I was wrong. – AnOldSoul Dec 21 '15 at 07:38
  • Well unless the question or code is _in_ C++ you shouldn't tag it. Only tag relevant tags. – Arc676 Dec 21 '15 at 07:39
  • 1
    It looks like BYTEWORD is a struct or union of some kind. Please provide the code where BYTEWORD is defined; then this code excerpt should make more sense. – Marc Khadpe Dec 21 '15 at 07:41
  • @MarcKhadpe sorry I missed this part of the code. typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef union { WORD w; struct { BYTE lo, hi; } b; } BYTEWORD; – AnOldSoul Dec 21 '15 at 07:42
  • @mayooran don't copy it into a comment. Copy it into your question. – eerorika Dec 21 '15 at 07:44
  • @mayooran Instead of trying to convert C++ specific code, why not use a function specially written in Java to perform the task of getting a CRC of the data? There has to be tons of Java examples that does this. If you don't know C++, how would you know the Java line-by-line translation will be equivalent? – PaulMcKenzie Dec 21 '15 at 07:45
  • I think that this could help you http://stackoverflow.com/questions/12372180/crc16-implementation-java – Holt Dec 21 '15 at 07:52
  • Tags have been fixed. There's nothing C++ unique to the code, so I removed the C++ tag. – Lundin Dec 21 '15 at 07:52
  • @Lundin can you check if the implementation in the modified question is correct? – AnOldSoul Dec 21 '15 at 09:27
  • @MarcKhadpe can you check if the implementation in the modified question is correct? – AnOldSoul Dec 21 '15 at 09:27
  • I have no idea, it depends on the polynomial. I'm assuming this is CRC16-CCITT with 0x1021 poly? You'd have to reverse-engineer that lookup table somehow to see if you get 0x1021. – Lundin Dec 21 '15 at 09:31
  • I mean implementation wise, is it equivalent to the C++ code? – AnOldSoul Dec 21 '15 at 09:32
  • Yes it looks ok implementation-wise, as far as I can tell. Been well over 10 years since I programmed in Java though :) – Lundin Dec 21 '15 at 09:35

2 Answers2

7

According to code I guess the BYTEWORD is a union of unsigned short and structure of two bytes, so the author could easily access high and low byte of this short, i.e.:

typedef union BYTEWORD
{
     short w;
     struct {
         char lo, hi;
     } b;
} BYTEWORD;

As java doesn't support unions (and as mentioned in discussion, there are endian flaws with the above), you will have to use >>, | and & operators to access to high and low 8 bits of the short:

  short retval_w = -1;
  ...
  retval_w = ((retval_w>>8)&0xff) ^ (ccittrev_tbl[(retval_w&0xff) ^ (data[i]&0xff)]);
Zbynek Vyskovsky - kvr000
  • 18,186
  • 3
  • 35
  • 43
  • Yes I think the same. 0xFFFF good indicator for short and hi looks pretty much to high byte access. – Stefan Dec 21 '15 at 07:46
  • 1
    You are probably correct about the union. But for the record, writing such unions is bad practice, because they are endianess-dependant. Instead, use shifts and bitwise `&` masks as shown here to get portable code. There is never a reason to write non-portable code when you can easily achieve portability with minimum effort. – Lundin Dec 21 '15 at 07:47
  • @Lundin: yes, I absolutely agree about the (non)quality of the original code, although as I haven't seen the original code, maybe there was at least `#if LOW_ENDIAN` block to handle the endianess. – Zbynek Vyskovsky - kvr000 Dec 21 '15 at 07:53
  • @ZbynekVyskovsky-kvr000 so this will be the only line in my code right? "retval_w = ((retval_w>>8)&0xff) ^ (ccittrev_tbl[(retval_w&0xff) ^ *ptr]);" – AnOldSoul Dec 21 '15 at 09:19
  • @ZbynekVyskovsky-kvr000 I have edited the question with what you said. Is it correct? Can I go with it? – AnOldSoul Dec 21 '15 at 09:25
  • @mayooran: Yes, it's correct. There is just one additional point - you'll have to replace `*ptr` with the current item from `data` array and cast it to unsigned (using &0xff), see updated answer. – Zbynek Vyskovsky - kvr000 Dec 21 '15 at 10:08
  • Thanks a lot mate! you are awesome. – AnOldSoul Dec 21 '15 at 10:30
0

The ^ is a binary operator which means Exclusive OR (XOR).

Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160
  • I was asking about the "retval.b.hi" line. If I convert retval to java it should be an int. Then how would I write retval.b.hi? – AnOldSoul Dec 21 '15 at 07:37
  • you mean retval is an int so there is properties of an int type? – Humam Helfawi Dec 21 '15 at 07:40
  • I was asking how there can be two properties called "b" and "hi" for the variable retVal? If you can check that line I had posted it shows, "retVal.b.hi^..." – AnOldSoul Dec 21 '15 at 07:40
  • Yes exactly! how can an int have properties like that? – AnOldSoul Dec 21 '15 at 07:41
  • you should see what is .b is and what is .b.h is and then you have two optition: 1) make a java class and put this attributes in it. 2)make static methods than can get you a 'b' and 'b.hu' from int – Humam Helfawi Dec 21 '15 at 07:41
  • It is all depends about what is .b and .b.hi – Humam Helfawi Dec 21 '15 at 07:42
  • @mayooran It is obviously defined as a union. I would assume the definition is: `typedef union { WORD w; struct { BYTE hi; BYTE lo; } b; } BYTEWORD;` or some other studid, endianess-dependant crap like that. Don't write such code. – Lundin Dec 21 '15 at 07:44
  • @HumamHelfawi I have edited the question, can you verify if the answer is correct? – AnOldSoul Dec 21 '15 at 09:26