How to convert this crc16 C implementation to java? [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Hi I have this C crc16 implementation:
const unsigned short CRCtbl[ 256 ] =
{
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
};
unsigned short Crc_16(unsigned char *str, int n)
{
unsigned short crc = 0xFFFF;
do
{
crc = ( crc >> 8 ) ^ CRCtbl[ ( crc & 0xFF ) ^ *str ];
str++;
}
while(--n);
return(crc);
}
I need to convert it into java one. My problem is that,since java does not provide unsigned int type, the implementation fails in some cases (some info[] byte >127 when considering it as unsigned).
private int crc_xor(byte[] info) {
int[] table = {
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};
int crc16=0;
int pos=0;
int lungh=info.length;
lungh-=1;
while(lungh>=0)
{
crc16 = ((crc16 >> 8) ^ table[(crc16&0xFF) ^ info[pos]]) & 0xFFFF;
pos+=1;
lungh-=1;
}
return crc16;
}
There are many java crc16 implementations but not this (used in SIA standard).
Can you help me?
thanks

Try changing the (crc16&0xFF) ^ info[pos] to (crc16 ^ info[pos])&0xFF.

Related

crc 16 bit array using java reading in full lines

hello I am trying to use this code to ultimately be able to add a file into it so it reads the file and runs through this crc16 but I keep getting this error
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Main.main(Main.java:51)
"
public class Main
{
public static void main(String[] args)
{
int[] table =
{
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,
};
byte[] bytes = args[0].getBytes();
int crc = 0x0000;
for (byte b : bytes)
{
crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff];
}
System.out.println("CRC16 = " + Integer.toHexString(crc));
}
}

Base64 encoding vs Ascii85 encoding

My project at work is using the Jackson JSON serializer to convert a bunch of Java objects into Strings in order to send them to REST services.
Some of these objects contain sensitive data, so I've written custom serializers to serialize these objects to JSON strings, then gzip them, then encrypt them using AES;
This turns the strings into byte arrays, so I use the Base64 encoder in Apache commons codec to convert the byte arrays into strings. The custom deserializers behind the REST interfaces reverse this process:
base64 decode -> decrypt -> decompress -> deserialize using default Jackson deserializer.
Base64 encoding increases the size of the output (the gzip step in serialization is meant to help ameliorate this increase), so I checked Google to see if there was a more efficient alternative, which led me to this previous stackoverflow thread that brought up Ascii85 encoding as a more efficient alternative -
Base64 adds 33% to the size of the output, Ascii85 adds 25% to the size of the output.
I found a few Java Ascii85 implementations e.g. Apache pdfbox, but I'm a bit leery to use the encoding - it seems like hardly anybody is using or implementing it, which might just mean that Base64 has more inertia, or which may instead mean that there's some wonky problem with Ascii85.
Does anybody know more on this subject? Are there any problems with Ascii85 that mean that I should use Base64 instead?
Base64 is way more common. The difference in size really isn't that significant in most cases, and if you add at the HTTP level (which will compress the base64) instead of within your payload, you may well find the difference goes away entirely.
Are there any problems with Ascii85 that mean that I should use Base64 instead?
I would strongly advise using base64 just because it's so much more widespread. It's pretty much the canonical way of representing binary data as text (unless you want to use hex, of course).
ASCII85 is a nice encoding to use to save that extra bit of space. But it outputs many characters that would need to be escaped if naively sent over HTTP. Base64 encoding has a variant that can be sent over HTTP without any escaping.
Here's a javascript ASCII85 encoder in case anyone needs to try:
// By Steve Hanov. Released to the public domain.
function encodeAscii85(input) {
var output = "<~";
var chr1, chr2, chr3, chr4, chr, enc1, enc2, enc3, enc4, enc5;
var i = 0;
while (i < input.length) {
// Access past the end of the string is intentional.
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
chr4 = input.charCodeAt(i++);
chr = ((chr1 << 24) | (chr2 << 16) | (chr3 << 8) | chr4) >>> 0;
enc1 = (chr / (85 * 85 * 85 * 85) | 0) % 85 + 33;
enc2 = (chr / (85 * 85 * 85) | 0) % 85 + 33;
enc3 = (chr / (85 * 85) | 0 ) % 85 + 33;
enc4 = (chr / 85 | 0) % 85 + 33;
enc5 = chr % 85 + 33;
output += String.fromCharCode(enc1) +
String.fromCharCode(enc2);
if (!isNaN(chr2)) {
output += String.fromCharCode(enc3);
if (!isNaN(chr3)) {
output += String.fromCharCode(enc4);
if (!isNaN(chr4)) {
output += String.fromCharCode(enc5);
}
}
}
}
output += "~>";
return output;
}
<input onKeyUp="result.innerHTML = encodeAscii85(this.value)" placeholder="write text here" type="text">
<p id="result"></p>
Here is matching ASCII85 AKA Base85 decoder (for user Qwerty) in JavaScript:
function decode_ascii85(a) {
var c, d, e, f, g, h = String, l = "length", w = 255, x = "charCodeAt", y = "slice", z = "replace";
for ("<~" === a[y](0, 2) && "~>" === a[y](-2), a = a[y](2, -2)[z](/\s/g, "")[z]("z", "!!!!!"),
c = "uuuuu"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33),
e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);
return function(a, b) {
for (var c = b; c > 0; c--) a.pop();
}(e, c[l]), h.fromCharCode.apply(h, e);
}
<input onKeyUp="result.innerHTML = decode_ascii85(this.value)" placeholder="insert encoded string here" type="text">
<p id="result"></p>
example: <xmp><~<+oue+DGm>#3BW*D/a<&+EV19F<L~></xmp>

Checksum issue CRC16CCITT

I have the following C-code which I am trying to re-write in java.
I would like to see similar outputs in both of them but I am getting different outputs.
This is for computation of checksum.
Here is the C-code:
#include <ctype.h>
#include <string.h>
#include <stdio.h>
/*~+:CRC Table*/
static unsigned short crctab[256] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
void convert_toASCII (char *buffer, int value)
{
/*
Function converts given 'value' into a 4 byte
ASCII-HEX-String (with leading zeros) to 'buffer[]'
Parameter: char *buffer, int value
Returns: none
*/
static unsigned char hex_num[] = "0123456789ABCDEF";
static unsigned char i; /* HV */
i = (char)((value & 0xf000) >> 12);
*buffer = (char)(hex_num[i]);
++buffer;
i = (char)((value & 0x0f00) >> 8);
*buffer = (char)(hex_num[i]);
++buffer;
i = (char)((value & 0x00f0) >> 4);
*buffer = (char)(hex_num[i]);
++buffer;
i = (char)(value & 0x000f);
*buffer = (char)(hex_num[i]);
}
void calc_crc(unsigned char *databuffer,unsigned int length)
{
/*~+:Modulname: calc_crc */
/*~+:Calculate serial CRC (according CCITT ) */
/*~+:The serial CRC16 is calculated for a certain length (int length) */
/*~+:over bytes in buffer (char databuffer[]) */
/*~+: */
/*~+:Input: *databuffer pointer to data string */
/*~+: laenge number of chars to build CRC for */
/*~+:Output: the CRC will be added in ASCII characters ( 4 chars) */
/*~+: at the end of the given string and terminated with '\0' */
/*~+: The buffer must be able to handle these additional */
/*~+: 5 characters */
static unsigned char tmp;
static unsigned int crc,zaehler;
crc = 0;
for (zaehler = 0;zaehler < length ;zaehler ++)
{
tmp=(unsigned char) (crc>>8) ;
crc=(crc<<8) ^ crctab[tmp] ^ *databuffer;
databuffer++;
}
printf("%u", crc);
/* convert crc -> ASCII */
/* append to string */
convert_toASCII (databuffer, crc);
}
void main(void)
{
static char Data[] = {"abcdefghij"};
static char buffer[64];
strcpy(buffer,Datensatz);
printf("Data : %s \n\r",&buffer[0]);
calc_crc(buffer,10);
printf("CRC : %s \n\r",&buffer[10]);
printf("Data mit CRC: %s \n\r",&buffer[0]);
}
The java code that I have written is:
public final class Checksum
{
public static void main(final String[] args)
{
final String checksumString = "abcdefghij";
final int checksum = calculateCRC16CCITTChecksum(checksumString);
System.out.println("Checksum integer value:" + checksum);
System.out.println("Checksum value in Hex:" + Integer.toHexString(checksum));
}
/**
* #param frame The frame for whose checksum has to be calculated.
* #return The calculated checksum.
*/
private final static int calculateCRC16CCITTChecksum(final String frame)
{
final int[] CRC16_Lookup = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252,
0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528,
0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5,
0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD,
0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E,
0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214,
0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F,
0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827,
0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C,
0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36,
0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0};
// check sum for polynomial 1.x16 + 0.x15 + 0.x14 + 0.x13 + 1.x12 + 0.x11 + 0.x10 + 0.x9 + 0.x8 + 0.x7 + 0.x6 + 1.x5 + 0.x4 + 0.x3 + 0.x2 +0.x1 + 1.x0.
// 1.x16 - implies 1 multiplied by 'x' to the power of 16.
int crc = 0;
for (int i = 0, size = frame.length(); i < size; i++)
{
crc = (crc << 8) ^ CRC16_Lookup[(crc >> 8) & 0xFF] ^ (frame.charAt(i) & 0xFF);
}
return crc & 0xFFFF;
}
}
The integer value output that I get in java code is different from what the decimal value that I get in C, even the hex string conversion in java yields different results to that of hex conversion in C.
Please guide me what I am doing wrong.
Thanks for looking!!
This is not strictly related to an implementation problem, but I guess it's worth mentioning anyway. Keep in mind that some communication protocols require XORing the input values and output values with some value, not to mention bit or byte reflecting of the input data. This happens in Ethernet, which uses CRC-32 for the actual calculations, but the input and output data is XORed with FF..FF (so, it's NOTed), and all the bits in the input byte (or, more naturally, nibble) are reflected. Keep that in mind - the actual calculations might be alright, but there might be something you're simply not aware of in terms of mangling the data, what leads to completely different results.
By code inspection, one can see that in Java the CRC is limited to 16 bits before being printed in decimal (use of & 0xFFFF before returning the function). In C, the value printed is the full unsigned int, so applying the same mask should do the trick.
I can't understand why the hex values differ, though...

Can I someone point to me what I did wrong? Trying to map VB to Java using JNA to access the library

Original Working VB_Code
Private Declare Function ConnectReader Lib "rfidhid.dll" () As Integer
Private Declare Function DisconnectReader Lib "rfidhid.dll" () As Integer
Private Declare Function SetAntenna Lib "rfidhid.dll" (ByVal mode As Integer) As Integer
Private Declare Function Inventory Lib "rfidhid.dll" (ByRef tagdata As Byte, ByVal mode As Integer, ByRef taglen As Integer) As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim desc As String
desc = "1. Click ""Connect"" to talk to reader." & vbCr & vbCr
desc &= "2. Click ""RF On"" to wake up the TAG." & vbCr & vbCr
desc &= "3. Click ""Read Tag"" to get tag PCEPC."
lblDesc.Text = desc
End Sub
Private Sub cmdConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdConnect.Click
If cmdConnect.Text = "Connect" Then
If ConnectReader() Then
cmdConnect.Text = "Disconnect"
Else
MsgBox("Unable to connect to RFID Reader. Please check reader connection.")
End If
Else
If DisconnectReader() Then
cmdConnect.Text = "Connect"
End If
End If
End Sub
Private Sub cmdRF_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRF.Click
If cmdRF.Text = "RF On" Then
If SetAntenna(&HFF) Then
cmdRF.Text = "RF Off"
End If
Else
If SetAntenna(&H0) Then
cmdRF.Text = "RF On"
End If
End If
End Sub
Private Sub cmdReadTag_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdReadTag.Click
Dim tagdata(64) As Byte
Dim taglen As Integer, cnt As Integer
Dim pcepc As String
pcepc = ""
If Inventory(tagdata(0), 1, taglen) Then
For cnt = 0 To taglen - 1
pcepc &= tagdata(cnt).ToString("X2")
Next
txtPCEPC.Text = pcepc
Else
txtPCEPC.Text = "ReadError"
End If
End Sub
Java Code (Simplified)
import com.sun.jna.Library;
import com.sun.jna.Native;
public class HelloWorld {
public interface MyLibrary extends Library {
public int ConnectReader();
public int SetAntenna (int mode);
public int Inventory (byte tagdata, int mode, int taglen);
}
public static void main(String[] args) {
MyLibrary lib = (MyLibrary) Native.loadLibrary("rfidhid", MyLibrary.class);
System.out.println(lib.ConnectReader());
System.out.println(lib.SetAntenna(255));
byte[] tagdata = new byte[64];
int taglen = 0;
int cnt;
String pcepc;
pcepc = "";
if (lib.Inventory(tagdata[0], 1, taglen) == 1) {
for (cnt = 0; cnt < taglen; cnt++)
pcepc += String.valueOf(tagdata[cnt]);
}
}
}
The error happens when lib.Inventory is run. lib.Inventory is used to get the tag from the RFID reader. If there is no tag, no error.
The error code
An unexpected error has been detected by Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0b1d41ab, pid=5744, tid=4584
Java VM: Java HotSpot(TM) Client VM (11.2-b01 mixed mode windows-x86)
Problematic frame:
C [rfidhid.dll+0x141ab]
An error report file with more information is saved as:
C:\eclipse\workspace\FelmiReader\hs_err_pid5744.log
At first blush, I suspect the problem is an incorrect type signature in the Inventory declaration.
If the parameter is ByRef, that implies a pointer (in C this would be a *byte instead of a byte). JNA has a DoubleByReference class type that you probably should be using. You'll have a similar issue with the 3rd parameter (which is really an int*, not an int as you have it coded).
As an FYI, the native crash that you are getting should leave a dump file in the application directory. If you open that up, you should find the native call that was in place when the failure occurred - I'll bet money that it was the lib.Inventory(tagdata[0], 1, taglen) call.
Figuring out exactly which call is causing the crash will be key to tracking it down.

How to get subnet mask of local system using java?

How do you get the Subnet mask address of the local system using Java?
the netmask of the first address of the localhost interface:
InetAddress localHost = Inet4Address.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength();
a more complete approach:
InetAddress localHost = Inet4Address.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
System.out.println(address.getNetworkPrefixLength());
}
/24 means 255.255.255.
You can convert the obtained value into the standard textual format like this:
short prflen=...getNetworkPrefixLength();
int shft = 0xffffffff<<(32-prflen);
int oct1 = ((byte) ((shft&0xff000000)>>24)) & 0xff;
int oct2 = ((byte) ((shft&0x00ff0000)>>16)) & 0xff;
int oct3 = ((byte) ((shft&0x0000ff00)>>8)) & 0xff;
int oct4 = ((byte) (shft&0x000000ff)) & 0xff;
String submask = oct1+"."+oct2+"."+oct3+"."+oct4;
java.net.InterfaceAddress in SE6 has a getNetworkPrefixLength method that returns, as the name suggests, the network prefix length. You can calculate the subnet mask from this if you would rather have it in that format. java.net.InterfaceAddress supports both IPv4 and IPv6.
getSubnetMask() in several network application APIs returns subnet mask in java.net.InetAddress form for specified IP address (a local system may have many local IP addresses)
I found that:
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
To get subnetmask for ipv6 we can use:
networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength();
To get subnetmask for ipv4 we can use:
networkInterface.getInterfaceAddresses().get(1).getNetworkPrefixLength();
I devised an IPv4 only solution that is simple enough. I needed that to generate netmask for subnetworks here in order to delegate those subnets correctly. I know I could have generated a table of the 32 possible masks, but I prefered to get it computed each time.
So here is my solution.
/*
* Get network mask for the IP address and network prefix specified...
* The network mask will be returned has an IP, thus you can
* print it out with .getHostAddress()...
*/
public static InetAddress getIPv4LocalNetMask(InetAddress ip, int netPrefix) {
try {
// Since this is for IPv4, it's 32 bits, so set the sign value of
// the int to "negative"...
int shiftby = (1<<31);
// For the number of bits of the prefix -1 (we already set the sign bit)
for (int i=netPrefix-1; i>0; i--) {
// Shift the sign right... Java makes the sign bit sticky on a shift...
// So no need to "set it back up"...
shiftby = (shiftby >> 1);
}
// Transform the resulting value in xxx.xxx.xxx.xxx format, like if
/// it was a standard address...
String maskString = Integer.toString((shiftby >> 24) & 255) + "." + Integer.toString((shiftby >> 16) & 255) + "." + Integer.toString((shiftby >> 8) & 255) + "." + Integer.toString(shiftby & 255);
// Return the address thus created...
return InetAddress.getByName(maskString);
}
catch(Exception e){e.printStackTrace();
}
// Something went wrong here...
return null;
}
You just call it with the IP and the prefix you want to use, it will generate the netmask for you.
I just finished working on an API for subnetting networks with Java.
https://launchpad.net/subnettingapi
it has that functionality and more.
Here is an answer, how to get a submask from WIFI connection: link
I adapted it for my needs, and here it is:
private static String intToIP(int ipAddress) {
String ret = String.format("%d.%d.%d.%d", (ipAddress & 0xff),
(ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff),
(ipAddress >> 24 & 0xff));
return ret;
}
public static String GetSubnetMask_WIFI() {
WifiManager wifiManager = (WifiManager) Global.getMainActivity()
.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
DhcpInfo dhcp = wifiManager.getDhcpInfo();
String mask = intToIP(dhcp.netmask);
return mask;
}
In summary, a method to obtain the mask would be like this:
public String mascara() throws SocketException{
try{
InetAddress localHost = Inet4Address.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
prefijo =
""+networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength();
int shft = 0xffffffff<<(32-
networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength());
int oct1 = ((byte) ((shft&0xff000000)>>24)) & 0xff;
int oct2 = ((byte) ((shft&0x00ff0000)>>16)) & 0xff;
int oct3 = ((byte) ((shft&0x0000ff00)>>8)) & 0xff;
int oct4 = ((byte) (shft&0x000000ff)) & 0xff;
mascara = oct1+"."+oct2+"."+oct3+"."+oct4;
// System.out.println(""+mascara);
}catch(UnknownHostException e){
System.out.println("Error: "+e);
}
return mascara;
}
FWIW, in the past I'd tried using InterfaceAddress.getNetworkPrefixLength() and InterfaceAddress.getBroadcast(), but they don't return accurate info (this is on Windows, with Sun JDK 1.6.0 update 10). The network prefix length is 128 (not 24, which it is on my network), and the broadcast address returned is 255.255.255.255 (not 192.168.1.255, which it is on my network).
James
Update: I just found the solution posted here:
http://forums.sun.com/thread.jspa?threadID=5277744
You need to prevent Java from using IPv6, so that it isn't getting to IPv4 via IPv6.
Adding -Djava.net.preferIPv4Stack=true to the command line fixes the results from InterfaceAddress.getNetworkPrefixLength() and InterfaceAddress.getBroadcast() for me.

Categories