1

我正在研究校验和算法,但遇到了一些问题。更重要的是,当我手工制作一个比我收到的“真实”数据小得多的“假”消息时,我得到了一个正确的校验和。但是,针对真实数据 - 校验和无法正常工作。

以下是有关传入数据/环境的一些信息:

  • 这是一个 groovy 项目(见下面的代码)
  • 出于校验和计算的目的,所有字节都将被视为无符号整数
    • 你会注意到一些短裤和多头的东西,以使这项工作发挥作用。
  • 实际数据的大小为 491 字节。
  • 我的样本数据(似乎添加正确)的大小是 26 字节
  • 据我所知,我的十六进制到十进制转换都没有产生负数
  • 文件中的某些字节不会添加到校验和中。我已经验证了这些开关是否正常工作,以及何时应该正常工作 - 所以这不是问题。
  • 我计算出来的校验和,和实际传输的校验和总是相差相同的数量。
  • 我已经手动验证了与真实数据打包的校验和是正确的。

这是代码:

// add bytes to checksum
public void addToChecksum( byte[] bytes) {
    //if the checksum isn't enabled, don't add
    if(!checksumEnabled) {
        return;
    }

    long previouschecksum =  this.checksum;

    for(int i = 0; i < bytes.length; i++) {
        byte[] tmpBytes = new byte[2];
        tmpBytes[0] = 0x00;
        tmpBytes[1] = bytes[i];

        ByteBuffer tmpBuf = ByteBuffer.wrap(tmpBytes);

        long computedBytes = tmpBuf.getShort();
        logger.info(getHex(bytes[i]) + " = " + computedBytes);
        this.checksum += computedBytes;
    }

    if(this.checksum < previouschecksum) {
        logger.error("Checksum DECREASED: " + this.checksum);
    }
    //logger.info("Checksum: " + this.checksum);
}

如果有人能在这个算法中找到任何可能导致偏离预期结果的东西,我将非常感谢您帮助追踪这一点。

4

2 回答 2

0

我在您的代码中没有看到您重置this.checksum.

这样,你应该总是得到一个this.checksum > previouschecksum,对吧?这是故意的吗?

否则我无法在您的上述代码中找到缺陷。也许您的“this.checksum”类型错误(例如缩写)。这可能会翻转,以便您获得负值。

这是这种行为的一个例子

import java.nio.ByteBuffer
short checksum = 0
byte[] bytes = new byte[491]
def count = 260
for (def i=0;i<count;i++) {
    bytes[i]=255
}
bytes.each { b ->
    byte[] tmpBytes = new byte[2];
    tmpBytes[0] = 0x00;
    tmpBytes[1] = b;
    ByteBuffer tmpBuf = ByteBuffer.wrap(tmpBytes);
    long computedBytes = tmpBuf.getShort();
    checksum += computedBytes
    println "${b} : ${computedBytes}"
}
println checksum +"!=" + 255*count

只是玩弄'count'变量的值,它以某种方式对应于您输入的长度。

于 2011-09-07T19:30:28.090 回答
0

您的校验和将不断增加,直到它翻转为负数(因为它是一个有符号长整数)

您还可以将方法缩短为:

public void addToChecksum( byte[] bytes) {
  //if the checksum isn't enabled, don't add
  if(!checksumEnabled) {
    return;
  }

  long previouschecksum =  this.checksum;
  this.checksum += bytes.inject( 0L ) { tot, it -> tot += it & 0xFF }

  if(this.checksum < previouschecksum) {
    logger.error("Checksum DECREASED: " + this.checksum);
  }
  //logger.info("Checksum: " + this.checksum);
}

但这并不能阻止它转向消极。为了为您生成哈希的每个项目节省 12 个字节,我仍然建议使用已知可以工作的 MD5 之类的东西可能比自己滚动更好......但是我知道有时您必须满足一些疯狂的要求依照...

于 2011-09-07T20:31:43.773 回答