Jeff Collins
asked on
BIT Operators VB6 and PHP
Following on from a related question at https://www.experts-exchange.com/questions/27303952/VB6-to-PHP-Code-Checksum.html
I have now a simple (not required to be 'tricky' or foolproof) key creator that I've put together in VB6 and have been using on my software for a number of years now. I have been trying to simulate that algorithm in PHP to generate the same 'key' so users can generate the access key online, instead of having to ring me.
The trick I'm finding is the codes are producing different keys. This may be related to how PHP and VB6 handle Bit Operators.
I've attached the code on both PHP and VB6.
Given an input string of say "1234-123-123-123JOE BLOW" the output in VB6 is 03FCGGFB, whilst the PHP output is 0017GD02
I've played a bit with the PHP code to try different things.
Any ideas would be great.
I have now a simple (not required to be 'tricky' or foolproof) key creator that I've put together in VB6 and have been using on my software for a number of years now. I have been trying to simulate that algorithm in PHP to generate the same 'key' so users can generate the access key online, instead of having to ring me.
The trick I'm finding is the codes are producing different keys. This may be related to how PHP and VB6 handle Bit Operators.
I've attached the code on both PHP and VB6.
Given an input string of say "1234-123-123-123JOE BLOW" the output in VB6 is 03FCGGFB, whilst the PHP output is 0017GD02
I've played a bit with the PHP code to try different things.
Any ideas would be great.
Public Function gencheck(sstring As String) As String
Dim I As Integer
Dim chk As Long
Dim n1, n2, n3, n4, n5, n6, n7, n8 As Byte
chk = 0
For I = 1 To Len(sstring)
chk = chk * 2
' Set bit 0 to whatever bit 16 is..
If (chk And 65536) = 0 Then
' Bit 16 is clear, so clear bit 0
chk = chk And 65534
Else
' Bit 16 is set, so set bit 0
chk = chk Or 1
End If
' Clear bit 16..
chk = chk And 65535
' XOR sum
chk = chk Xor Asc(Mid$(sstring, I, 1))
Next I
' We have the additive checksum, so now get the 4 nybbles..
n8 = chk And 15
chk = Int(chk / 4)
n7 = chk And 15
chk = Int(chk / 4)
n6 = chk And 15
chk = Int(chk / 4)
n5 = chk And 15
chk = Int(chk / 4)
n4 = chk And 15
chk = Int(chk / 4)
n3 = chk And 15
chk = Int(chk / 4)
n2 = chk And 15
chk = Int(chk / 4)
n1 = chk And 15
' Add 48 to each one (ascii '0')
n1 = n1 + 48
If n1 > 57 Then
n1 = 65 + (n1 - 57)
End If
n2 = n2 + 48
If n2 > 57 Then
n2 = 65 + (n2 - 57)
End If
n3 = n3 + 48
If n3 > 57 Then
n3 = 65 + (n3 - 57)
End If
n4 = n4 + 48
If n4 > 57 Then
n4 = 65 + (n4 - 57)
End If
n5 = n5 + 48
If n5 > 57 Then
n5 = 65 + (n5 - 57)
End If
n6 = n6 + 48
If n6 > 57 Then
n6 = 65 + (n6 - 57)
End If
n7 = n7 + 48
If n7 > 57 Then
n7 = 65 + (n7 - 57)
End If
n8 = n8 + 48
If n8 > 57 Then
n8 = 65 + (n8 - 57)
End If
gencheck = Chr$(n1) + Chr$(n2) + Chr$(n3) + Chr$(n4) + Chr$(n5) + Chr$(n6) + Chr$(n7) + Chr$(n8)
End Function
function getchecksum($sstring){
$chk = 0;
$len = strlen($sstring);
for ($I=1; $I<=$len; $I++){
$chk = $chk * 2;
// Set bit 0 to whatever bit 16 is..
If (($chk & 65536) == 0 ){
// Bit 16 is clear, so clear bit 0
$chk = ($chk & 65534);
} else {
// Bit 16 is set, so set bit 0
$chk = ($chk Or 1);
}
// Clear bit 16..
$chk = ($chk & 65535);
// XOR sum
$chk = ($chk ^ Ord(substr($sstring, $I, 1)));
}
$n8 = ($chk & 15);
$chk = intval($chk / 4);
$n7 = ($chk & 15);
$chk = intval($chk / 4);
$n6 = ($chk & 15);
$chk = intval($chk / 4);
$n5 = ($chk & 15);
$chk = intval($chk / 4);
$n4 = ($chk & 15);
$chk = intval($chk / 4);
$n3 = ($chk & 15);
$chk = intval($chk / 4);
$n2 = ($chk & 15);
$chk = intval($chk / 4);
$n1 = ($chk & 15);
// Add 48 to each one (ascii '0')
$n1 = $n1 + 48;
If ( $n1 > 57 ){
$n1 = 65 + ($n1 - 57);
}
$n2 = $n2 + 48;
If ( $n2 > 57 ){
$n2 = 65 + ($n2 - 57);
}
$n3 = $n3 + 48;
If ( $n3 > 57 ){
$n3 = 65 + ($n3 - 57);
}
$n4 = $n4 + 48;
If ($n4 > 57){
$n4 = 65 + ($n4 - 57);
}
$n5 = $n5 + 48;
If ($n5 > 57){
$n5 = 65 + ($n5 - 57);
}
$n6 = $n6 + 48;
If ($n6 > 57){
$n6 = 65 + ($n6 - 57);
}
$n7 = $n7 + 48;
If ($n7 > 57){
$n7 = 65 + ($n7 - 57);
}
$n8 = $n8 + 48;
If ($n8 > 57 ){
$n8 = 65 + ($n8 - 57);
}
return chr($n1).chr($n2).chr($n3).chr($n4).chr($n5).chr($n6).chr($n7).chr($n8);
}
Bingo! I got it. One moment while I put some clean docs together. The PHP script needs two adjustments.
OK, I created a spreadsheet with the analysis I did (cleaned up from my initial work.) It seemed like an easy way to organize the results to easily see how I identified the two issues with the PHP script, and provide an easy way for you to reproduce my analysis.
See the attached spreadsheet for the details, the first tab is especially enlightening, but, in summary....
In your question above:
1) line 18 uses substr() which uses a 0-based string reference, but $i is counting 1-based, so it was picking up the wrong character in your string.
2) line 12 uses "Or" operator and it should be "|" in PHP. (Not sure why "Or" worked at all. It's probably applicable in some situation.)
ChecksumFunctionsAnalysis.xls
See the attached spreadsheet for the details, the first tab is especially enlightening, but, in summary....
In your question above:
1) line 18 uses substr() which uses a 0-based string reference, but $i is counting 1-based, so it was picking up the wrong character in your string.
2) line 12 uses "Or" operator and it should be "|" in PHP. (Not sure why "Or" worked at all. It's probably applicable in some situation.)
ChecksumFunctionsAnalysis.xls
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thats is absolutely brilliant.
Thank you kbirecki, especially for the spreadsheet analysis.
As you may have gathered, I'm running abit blind on PHP, having spent so long developing using VB6, however am enjoying the learning curve in moving over to PHP.
Thank you kbirecki, especially for the spreadsheet analysis.
As you may have gathered, I'm running abit blind on PHP, having spent so long developing using VB6, however am enjoying the learning curve in moving over to PHP.
Happy to help. I'm doing the same. Next up: C#!
ASKER