算法相同,结果不同

时间:2012-07-26 12:32:03

标签: php c++ hash

美好的一天,我正在进行哈希算法,所以我用PHP将其重写为C ++。 但是C ++的结果与php结果不同。 PHP结果包含10个以上的字符,C ++结果只包含6到8个字符。但PHP结果的最后8个字符与C ++结果相同。 所以这是PHP代码:

<?php function JL1($text) { 
$text.="XQ";
$length=strlen($text);
$hash=0;        
for($j=0;$j<$length;$j++) {
    $p=$text[$j];
    $s=ord($p);
    if($s%2==0) $s+=9999;
    $hash+=$s*($j+1)*0x40ACEF*0xFF;                         
}       
$hash+=33*0x40ACEF*0xFF;
$hash=sprintf("%x",$hash);
return $hash; } ?>

这里是C ++代码:

char * JL1(char * str){
int size=(strlen(str)+3),s=0; //Edit here (+2 replaced with +3)
if(size<=6) //Edit here (<9 replaced with <=6)
    size=9;
char *final=new char[size],temp;
strcpy(final,str);
strcat(final,"XQ");
long length=strlen(final),hash=0L;
for(int i=0;i<length;i++){
    temp=final[i];
    s=(int)temp;    
    if(s%2==0)s+=9999;
    hash+=((s)*(i+1)*(0x40ACEF)*(0xFF));
}
hash+=33*(0x40ACEF)*(0xFF);
sprintf(final,"%x",hash); //to hex string
final[8]='\0';
return final; }

单词的C ++结果示例:“嗨!” :053c81be PHP的结果就是这个词:324c 053c81be

有谁知道,错误在哪里以及如何解决这个问题,无论是在php还是在cpp代码中? 顺便说一句,当我在php结果中删除那些第一个字母时,我得到了C ++结果,但它没有帮助,因为C ++结果不能长达8个字符,在某些情况下它可能只有6个字符。

3 个答案:

答案 0 :(得分:2)

从哪里开始...

数据类型在C或C ++中没有固定的保证大小。因此,hash可能会在每次迭代时溢出,或者它可能永远不会溢出。

char可以是signedunsigned,因此对于同一个字符,将一个转换为整数可能会在不同的实现上产生负值和正值。

在将final的值打印到hash时,您可能正在写strcat。将第9个字符设置为0时,您可能也会过早地剪掉字符串。

如果final长度至少为7个字符,

str将在s的末尾写入。

temp,一个相对短暂的临时变量,太快宣布了。与33*(0x40ACEF)*(0xFF)相同。

您的代码看起来非常拥挤,几乎没有空白,并且很难阅读。

表达式“0x4DF48431L”溢出;你的意思是std::string吗?

在处理C ++中的字符串时,请考虑使用{{1}}而不是char数组。

答案 1 :(得分:1)

这里似乎有一个错误......

int size=(strlen(str)+2),s=0; 
if(size<9)     
    size=9; 
char *final=new char[size],temp; 
strcpy(final,str); 
strcat(final,"XQ");

如果strlen说10,那么大小将为12,将分配12个字符。 然后复制原始的10个字符,并添加XQ,但最终终止\ 0将在分配的内存之外。

不确定这是不是你的错,但它没有;看起来不错

答案 2 :(得分:1)

    C ++中的
  1. long hash很可能仅限于您平台上的32位。 PHP的数字不是。

  2. sprintf(final, "%x", hash)会产生可能不正确的结果。 %x将参数解释为unsigned int,在Windows和Linux x64上均为32位。所以它将long解释为unsigned int,如果long超过32位,则结果将被截断。

  3. 查看aib提出的所有问题。特别是结果提前终止。

  4. 你需要自己处理第3点,但我可以回答前两点。您需要将结果钳位到32位:$hash &= 0xFFFFFFFF;

    如果你输入 final 值,php代码将产生与x64 Linux上的C ++代码相同的结果(这意味着64位整数用于中间结果)。

    如果在每次计算后将其钳制,您应该得到与32位平台或Windows x64(中间结果的32位整数)上的C ++代码相同的结果。