校验和算法产生不可预测的结果

时间:2011-09-07 19:04:05

标签: groovy checksum unsigned-integer

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

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

  • 这是一个常规项目(见下面的代码)
  • 为了校验和计算,所有字节都将被视为无符号整数
    • 你会注意到为了实现这一目标,需要一些短裤和长裤。
  • 实际数据的大小为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);
}

如果任何人都可以在此算法中找到可能导致预期结果偏离的任何内容,我将非常感谢您帮助跟踪此问题。

2 个答案:

答案 0 :(得分: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'变量的值,该变量以某种方式对应于输入的长度。

答案 1 :(得分: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那样知道工作可能比滚动你自己更好...但是我知道有时你需要疯狂的要求坚持......