用Java计算CRC8校验和 [英] Calculate CRC8-Maxim checksum in Java

查看:264
本文介绍了用Java计算CRC8校验和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用Java编写CRC8-Maxim计算器,但遇到问题。我尝试了许多API,例如Jacksum,但没有任何应有的效果。
我发现的唯一东西是这个网站: http:// www。 sunshine2k.de/coding/javascript/crc/crc_js.html

I'm trying to code a CRC8-Maxim calculator in java but I'm stuck. I've tried many API's such as Jacksum, but nothing worked like it should. The only thing I found is this website: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

如果我选择CRC8-Maxim设置,结果正是我所需要的是。
(示例:VR1的校验和,应为D7)

If I choose the CRC8-Maxim setting, the result is exactly what I need it to be. (example: The checksum of VR1,?, should be D7)

您有任何想法,如何用Java编写代码?
我的最后一个学校项目需要它,而且没有多少时间了。

Do you have any idea, how I could code that in java? I need it for my final school project and there's not much time left.

在此先感谢您!
Benedikt

Thanks in advance! Benedikt


我尝试使用此代码。它具有与网站上的计算器相同的查找表和相同的多项式。

I tried it with this Code. It has the same lookup table and the same polynomial as the calculator at the website.

import java.io.UnsupportedEncodingException;

public final class Crc8 {

private static final short CRC8_POLYNOMIAL = 0x31;
private static final short CRC8_INIT_VALUE = 0x0;
private static final short[] CRC8_LOOKUP_TABLE = {
    0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97, 0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E,
    0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4, 0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D,
    0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11, 0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8,
    0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52, 0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB,
    0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA, 0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13,
    0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9, 0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50,
    0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C, 0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95,
    0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F, 0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6,
    0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED, 0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54,
    0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE, 0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17,
    0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B, 0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2,
    0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28, 0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91,
    0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0, 0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69,
    0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93, 0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A,
    0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56, 0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF,
    0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15, 0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC
};

private final boolean useLookupTable;
private short crc8;

public Crc8() {
    this(true);
}

public Crc8(boolean use_lookup_table) {
    useLookupTable = use_lookup_table;
    reset();
}

public Crc8 reset() {
    crc8 = CRC8_INIT_VALUE;
    return (this);
}

public Crc8 update(byte b) {
    if (useLookupTable) {
        crc8 = CRC8_LOOKUP_TABLE[(crc8 ^ b) & 0xFF];
    } else {
        crc8 ^= b;
        crc8 &= 0xFF;
        for (int j = 0; j < 8; j++) {
            if ((crc8 & 1) == 1) {
                crc8 >>= 1;
                crc8 ^= CRC8_POLYNOMIAL;
            } else {
                crc8 >>= 1;
            }
        }
    }
    return (this);
}

public Crc8 update(byte[] data, int offset, int length) {
    for (int i = offset; i < length; i++) {
        update(data[i]);
    }
    return (this);
}

public Crc8 update(byte[] data) {
    return update(data, 0, data.length);
}

public Crc8 update(String s) {
    try {
        return update(s.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException ex) {
        throw new RuntimeException(ex);
    }
}

public short get() {
    return ((short) (crc8 ^ 0xFF));
}

/**
 * Return calculated CRC8 in 2 capital hex digits with leading zeros.
 */
public String getHex() {
    return (String.format("%02X", get()));
}}

这是Main-class

And this was the Main-class

public static void main(String[] args) {
    Crc8 crc = new Crc8(true);
    String input = "VR1,?,";
    crc.update(input);
    System.out.println("Input: " + input);
    String result  = crc.getHex();
    System.out.println("Output: " + result);

}

但毫无疑问,结果是E4而不是D7

But unfournatly the result was E4 and not D7

推荐答案

考虑到Java没有未签名的 ints 。这将影响您的右移运算符,>> = 。该链接对此进行了讨论:什么是Java的unsigned等效项?。我认为,对于您要执行的操作,重要的部分是:

Consider that java doesn't have unsigned ints. This is going to affect your right shift operators, >>=. This link talks about it: What is the Java equivalent of unsigned?. I think the important part, for what you're trying to do, is this:


有符号与无符号移位

Signed vs unsigned shifts

重要的例外是右移位运算符,由两个大于表示。符号:>>。在C / C ++和Java中,此运算符都执行符号扩展:即,将数字的位向右移动一位,同时保留符号。具体来说,执行移位后,它将符号位(最左边的位)复制到最左边的位置。

An important exception is the right shift operator, represented by two "greater than" symbols: >>. In both C/C++ and Java, this operator performs sign extension: that is, as well as shifting the bits of the number one place to the right, it preserves the sign. Specifically, after performing the shift, it copies the sign bit (the leftmost bit) into the leftmost position.

现在,如果我们将整数视为无符号的,那么我们就不会要复制符号位,因为它实际上并不代表符号!相反,我们希望将其保留为零。为了实现这一点,在Java中,我们编写>>而不是编写>>。这种移位的变体有时称为逻辑移位,而先前的变体(考虑符号)是算术移位。实际上,在机器代码级别上,大多数体系结构为两次转换提供了不同的指令,并且C / C ++编译器会根据我们是否已将相关变量声明为未签名来选择合适的指令。在Java中,我们必须明确地说出所需的类型。

Now, if we're treating an integer as unsigned, then we don't want to copy the sign bit, because it doesn't actually represent the sign! Instead, we want to leave it as zero. To achieve this, in Java, instead of writing >>, we write >>>. This variant of the shift is sometimes called a logical shift, and the previous variant— which takes account of the sign— an arithmetic shift. At the machine code level, most architectures in fact provide different instructions for the two shifts, and the C/C++ compiler chooses the appropriate one depending on whether we've declared the variable in question as unsigned. In Java, we must explicitly say which type we require.

编辑:尝试将这些十六进制值放入 5652312C3F2C 放入 Eric的Maxim / Dallas 1-Wire在线CRC计算器。它提供了D7并提供了许多调试信息,这些信息应该可以帮助您找出问题所在。

Try putting these hex values 5652312C3F2C into Eric's Maxim/Dallas 1-Wire Online CRC Calculator . It gives D7 and gives a bunch of debug information that should help you figure out where you're going wrong.

这篇关于用Java计算CRC8校验和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆