0

we are sending some data over a serial line, and i can do pretty much everything via a bash script (instead of code), except for the crc16 calculation. if i can do it all in scripts versus code, it would make configuration a heckofalot easier (especially while in the field).

i'm alright with commands, but i lose all ability when we get to the tricky stuff.

so my question is, can someone do a rewrite of this CRC16 for me, but within bash?

here is the algorithm grabbed from wikipedia, and it is the one in our code:

uint16_t Encoder::checksum(std::string thestring)
{
    uint8_t d, e, f;
    uint16_t c, r, crccalc;
    c = 0xffff;

    for (unsigned int i = 0; i < thestring.length(); i++)
    {
        d = thestring[i];
        e = c ^ d;
        f = e ^ (e << 4);
        r = (c >> 8) ^ (f << 8) ^ (f << 3) ^ (f >> 4);
        c = r;
    }
    c ^= 0xffff;
    crccalc = c;
    return crccalc;
}

i can easily create an executable out of the C++ code, and just feed it stdin, but i think it would be really neat to be able to have this within the bash.

the other thing i don't know is how to ensure that my variable sizes are correct. how can i ensure that i am getting a 16 bit integer?

any help would be great. i found a little script online, but i didn't trust it. thought it would be really cool to have answered here.

jasonmclose
  • 1,667
  • 4
  • 22
  • 38

1 Answers1

0

Bash have:

  • xor ($((5^2)) will be 7);
  • left shift ($(3<<2) will be 12);
  • right shift ($(8>>2) will be 2);
  • hexademical numbers support ($((0xFF)) will be 255).

Nothing comes to mind to convert from 32 (64) to 16 bit integer in pure Bash but you can do it with awk:

$ echo 65536 | awk '{printf("%hu\n",$1)}'
0

This should be enough to rewrite algorithm in Bash.

Matvey Aksenov
  • 3,802
  • 3
  • 23
  • 45
  • hey, thanks. i know that bash has a lot of those operators, but i'm not sure on maintaining the size of the variables. would've never thought to have used awk for that. – jasonmclose Dec 15 '11 at 14:03
  • 1
    i am going to go ahead and create a little program that uses the C++ code, and reads in the string from standard in, and then gives the crc. then, i will give the bash part an attempt. that way, i'll know if i am doing it right (based upon if the output of the bash function matches the C++ code) – jasonmclose Dec 15 '11 at 14:04
  • If you're going to use awk, gawk (typically what you get with linux) has left-right shift, xor, etc. **as named operators** (they look like fuctions) See http://www.gnu.org/s/gawk/manual/gawk.html#index-left-shift_002c-bitwise-1459 . Just do it all in gawk! Good luck. – shellter Dec 15 '11 at 15:26
  • i was able to get this problem done, and answered properly in this thread: http://stackoverflow.com/questions/8564267/crc16-algorithm-from-c-to-bash – jasonmclose Dec 20 '11 at 13:23