2011-10-16 3 views
7

내가 그 문자열을 기반으로 해시 정수를 문자열을 받아 생산 델파이 비교적 간단한 기능을 가지고 PHP하기 똑같다. 이것은 내가 PHP에있어 무엇 :델파이 비트 PROC 변환은

당신은 델파이 함수에 문자열 TestString에 전달하면
function HashElf($Buf, $BufSize){ 
    $Bytes = str_split($Buf); 

    for ($i= 0; $i<$BufSize;$i++){ 
    $Result = ($Result << 4) + Ord($Bytes[$i]); 

    $X = $Result & (0xF0000000); 
    if ($X<>0){$Result = $Result^($X>>24);} 

    $Result = ($Result & (~ $X)); 
    } 
    return $Result; 
} 

당신은 195,831,015 그러나 PHP 내가 차이는 7 자 이후에 분명하게 발견 72559895.을 반환받을. 테스트 문자열이 테스트 일 경우 결과는 동일합니다.

PHP 예를 들면 오른쪽으로 folowing 라인 음수 시프트 일부 어려움을 보인다 :

if ($X<>0){$Result = $Result^($X>>24);} 

< < (24)는 변수 X 델파이과 동일한 값을 생성 좌측 $의 X 시프트 변경 그러나 결과는 여전히 다릅니다.

내가 여기에 정말 분명한 것을 놓치고 있습니까?

편집 : 두 함수의 출력은 다음과 같습니다

델파이

Char: t Result: 116  X: 0 
    Char: e Result: 1957  X: 0 
    Char: s Result: 31427  X: 0 
    Char: t Result: 502948  X: 0 
    Char: s Result: 8047283 X: 0 
    Char: t Result: 128756644 X: 0 
    Char: r Result: 181058242 X: 1879048192 
    Char: i Result: 212577321 X: -1610612736 
    Char: n Result: 180011582 X: -1073741824 
    Char: g Result: 195831015 X: -1610612736 

PHP는

Char: t $Result: 116   $X: 0 
    Char: e $Result: 1957  $X: 0 
    Char: s $Result: 31427  $X: 0 
    Char: t $Result: 502948  $X: 0 
    Char: s $Result: 8047283 $X: 0 
    Char: t $Result: 128756644 $X: 0 
    Char: r $Result: 181058242 $X: 1879048192 
    Char: i $Result: 212577417 $X: -1610612736 
    Char: n $Result: 180013310 $X: -1073741824 
    Char: g $Result: 195858503 $X: -1610612736 

그래서 그 문자는 "내가"그 PHP 트랙을 하차하기 시작하지 때까지 계산과 함께

EDIT2 :

추가 PHP 함수를 산술 시프트 대신 논리적 오른쪽 시프트를 할 수 :

function lshiftright($var,$amt) 
{ 
    $mask = 0x40000000; 
    if($var < 0) 
    { 
    $var &= 0x7FFFFFFF; 
    $mask = $mask >> ($amt-1); 
    return ($var >> $amt) | $mask; 
    }else{ 
    return ($var >> $amt); 
    } 
} 

이 지금 작동합니다! 또한 감사 마스크 아이디어에 대한 이그나시오 :)

답변

1

델파이가 맞고 PHP가 틀렸습니까?

델파이의 shl과 shr은 정수로 예측할 수없는 것처럼 보입니다. 참조 : http://www.merlyn.demon.co.uk/del-bits.htm#SAR. 스톡턴 박사는 두 가지 유형의 시프트 연산이 있음을 암시하는 것으로 보입니다. 산술 시프트 (부호 유지)와 논리 시프트입니다.

문서 (http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/expressions_xml.html)는 부호있는 정수에 shl/shr의 효과에 대해 명확하지 않습니다. 그러나 그들은 shr/shl이 하나의 숫자에 대해서만 div30/multiplication에 2와 같음을 언급한다. 부호가없는 인 경우.

스톡턴 (첫 번째 링크에서)이 논리적 인 시프트 조작을 호출하는 것을 찾을 수 없지만 논리적 인 것처럼 보입니다 :-) 부호없는 8 바이트 유형을 사용하도록 델파이 구현을 변경하십시오 (DWORD가옵니다. 마음에) 어떤 효과가 있는지 확인하십시오.

+0

힌트를 주셔서 감사합니다. PHP 매뉴얼을 다시 살펴보면 비트 쉬프트가 산수 일 뿐이라는 것을 알 수 있습니다. 추가 비트 마스크를 사용하여 델파이에서 작업 했었지만 PHP로 하여금 원하는 것을 수행하도록하는 것이 더 낫다는 것을 알았습니다 - 추가 코드 편집 참조 – Rucia

1

당신이 원하는 비트를 가면.

if ($X<>0){$Result = ($Result^($X>>24)) & 0xFF;} 
+0

내가 필요한 비트 수는 0x7FFFFFFF이지만 감사합니다.이는 결과가 여전히 Delphi와 PHP간에 일치하지 않음을 의미합니다. 또한 두 루틴은 서로 연계되어 실행되므로 매번 동일한 결과를 생성해야합니다. – Rucia

+0

24 비트를 오른쪽 시프트하는 중이라면 8 비트 만 남습니다. –