perl校验和计算迁移到java

ttisahbt  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(367)

我的任务是将perl程序迁移到java。
我遇到了一些麻烦,perl中有一个计算校验和的函数

sub ComputeChecksum  {
   my ($val) = @_;

   $value= 0;
   $multiplier = 1;

   $dlength=length($val);
   for($i=0; $i<$dlength; $i++) {
      $ival=ord(substr($val, $i, 1));
      $ival*=$multiplier;
      $value+=$ival/100000;
      $value+=$ival%100000;
      $multiplier%=2;
      $multiplier++;
   }
   $value%=100000;
   $value=(100000-$value)%100000;
   return ($value);
}

我将这段代码翻译成java,如下所示

private static long computeCheckSum(String id){
    long value = 0;
    long multiplier = 1;

    int dlength = id.length();

    for(int i=0; i< dlength; i++){
        int ival = id.charAt(i);
        ival *= multiplier;
        value += ival/100000;
        value += ival%100000;
        multiplier %= 2;
        multiplier++;
    }
    value %= 100000;
    value = ((100000-value)%100000);

    return value;
}

但在验证数据库中的旧数据时,我遇到了一个问题,java中计算的校验和与perl以前计算的校验和不匹配的时间大约有5%,而且有1%的时间没有匹配。
下面是一些旧数据和java结果的示例

Perl    Java
ff08ccfba8ad417db2857fc8933788af:96410 / 96409
ff163b2b2e3ef18265d08cc8965b864d:96533 / 96532
ff3848ff301b534b609148af93b2c9ce:96626 / 96625
ff48ec78ea190f44233c9050fd73137d:96631 / 96630
ff62234601e28e6f5d7ff89d95afbec0:96424 / 96423
ff78f4cabe5a565a1cdf11f752f13654:96495 / 96494
ff89dc6b86a535ef265727af90a9b6b3:96596 / 96595
ff98337de5eb9e60f1db51dbd14a4dd2:96366 / 96365
fff76022c6f9f7794793141a9f2a00d2:96813 / 96812

在这些集合中,第一部分是数据库中的数据,它由uid、分号和perl计算的校验和组成。这就是数据保存在数据库中的方式。
为了进行比较,我添加了斜杠和由java代码使用uid部分计算的结果。
有人能告诉我为什么会发生这种事吗?我需要能够计算正确的校验和100%的时间。

更新:
我改变了我的java代码,用float而不是int进行所有计算,结果更有趣的是,差异在同一组UID中,但不是生成1的差异,而是2的差异。
我正在考虑重新计算所有uid的校验和,并更新所有受影响的表。

yqyhoc1h

yqyhoc1h1#

印刷 $ival/100000 对于 ff08ccfba8ad417db2857fc8933788af 提供以下信息:

0.00102
0.00204
0.00048
0.00112
...

我不知道这个除法在java程序中是否是整数除法,但无论哪种方法,它都等于加零。这是不同的。
顺便说一下,我怀疑perl程序是有缺陷的。我怀疑需要整数除法( int($ival/100000) ),但意外使用了浮点除法。
也就是说,对于您提供的数字,差异似乎不足以产生结果,即使用 int($ival/100000) 产生与相同的结果 $ival/100000 . 显然还有另一个区别。
…还是有?添加

while (<DATA>) {
   chomp;
   say $_, ":", ComputeChecksum($_);
}

__DATA__
ff08ccfba8ad417db2857fc8933788af
ff163b2b2e3ef18265d08cc8965b864d
ff3848ff301b534b609148af93b2c9ce
ff48ec78ea190f44233c9050fd73137d
ff62234601e28e6f5d7ff89d95afbec0
ff78f4cabe5a565a1cdf11f752f13654
ff89dc6b86a535ef265727af90a9b6b3
ff98337de5eb9e60f1db51dbd14a4dd2
fff76022c6f9f7794793141a9f2a00d2

我得到了您所说的java结果(即使 $ival/100000 ):

ff08ccfba8ad417db2857fc8933788af:96409
ff163b2b2e3ef18265d08cc8965b864d:96532
ff3848ff301b534b609148af93b2c9ce:96625
ff48ec78ea190f44233c9050fd73137d:96630
ff62234601e28e6f5d7ff89d95afbec0:96423
ff78f4cabe5a565a1cdf11f752f13654:96494
ff89dc6b86a535ef265727af90a9b6b3:96595
ff98337de5eb9e60f1db51dbd14a4dd2:96365
fff76022c6f9f7794793141a9f2a00d2:96812

相关问题