I am trying to get the same MD5 hash in PHP and VB.NET but no matter what text encoding I use I cannot get the hashes to match. What am I doing wrong? Below is my code in each language:
PHP Code:
echo '<b>$20.00 (UTF-32)</b> = ' . md5(mb_convert_encoding('1C9BRPS3TN85I2ULE5FP' + '20.00', 'UTF-32'));
echo '<b>$20.00 (UTF-32LE)</b> = ' . md5(mb_convert_encoding('1C9BRPS3TN85I2ULE5FP' + '20.00', 'UTF-32LE'));
echo '<b>$20.00 (UTF-32BE)</b> = ' . md5(mb_convert_encoding('1C9BRPS3TN85I2ULE5FP' + '20.00', 'UTF-32BE'));
echo '<b>$20.00 (UTF-8)</b> = ' . md5(mb_convert_encoding('1C9BRPS3TN85I2ULE5FP' + '20.00', 'UTF-8'));
echo '<b>$20.00 (UTF-7)</b> = ' . md5(mb_convert_encoding('1C9BRPS3TN85I2ULE5FP' + '20.00', 'UTF-7'));
echo '<b>$20.00 (UTF-16)</b> = ' . md5(mb_convert_encoding('1C9BRPS3TN85I2ULE5FP' + '20.00', 'UTF-16'));
echo '<b>$20.00 (UTF-16LE)</b> = ' . md5(mb_convert_encoding('1C9BRPS3TN85I2ULE5FP' + '20.00', 'UTF-16LE'));
echo '<b>$20.00 (UTF-16BE)</b> = ' . md5(mb_convert_encoding('1C9BRPS3TN85I2ULE5FP' + '20.00', 'UTF-16BE'));
echo '<b>$20.00 (ASCII)</b> = ' . md5(mb_convert_encoding('1C9BRPS3TN85I2ULE5FP' + '20.00', 'ASCII'));
VB.NET Code:
Try
' Create a new instance of the MD5 object.
Dim md5Hasher As MD5 = MD5.Create()
' Convert the input string to a byte array and compute the hash.
Dim strInput As String = "1C9BRPS3TN85I2ULE5FP" & "20.00"
Dim data As Byte() = md5Hasher.ComputeHash(Encoding.UTF32.GetBytes(strInput))
' Create a new Stringbuilder to collect the bytes
' and create a string.
Dim sBuilder As New StringBuilder()
' Loop through each byte of the hashed data
' and format each one as a hexadecimal string.
Dim i As Integer
For i = 0 To data.Length - 1
sBuilder.AppendFormat("{0:x2}", data(i))
'sBuilder.Append(data(i).ToString("x2"))
Next i
lblResponse.Text = "<b>$20.00 (UTF-32)</b> = " & sBuilder.ToString() & "<br>"
' Try a different encoding
data = md5Hasher.ComputeHash(Encoding.ASCII.GetBytes(strInput))
' Loop through each byte of the hashed data
' and format each one as a hexadecimal string.
sBuilder.Length = 0
For i = 0 To data.Length - 1
sBuilder.AppendFormat("{0:x2}", data(i))
Next i
lblResponse.Text &= "<b>$20.00 (ASCII)</b> = " & sBuilder.ToString() & "<br>"
' Try a different encoding
data = md5Hasher.ComputeHash(Encoding.Unicode.GetBytes(strInput))
' Loop through each byte of the hashed data
' and format each one as a hexadecimal string.
sBuilder.Length = 0
For i = 0 To data.Length - 1
sBuilder.AppendFormat("{0:x2}", data(i))
Next i
lblResponse.Text &= "<b>$20.00 (Unicode)</b> = " & sBuilder.ToString() & "<br>"
' Try a different encoding
data = md5Hasher.ComputeHash(Encoding.UTF7.GetBytes(strInput))
' Loop through each byte of the hashed data
' and format each one as a hexadecimal string.
sBuilder.Length = 0
For i = 0 To data.Length - 1
sBuilder.AppendFormat("{0:x2}", data(i))
Next i
lblResponse.Text &= "<b>$20.00 (UTF7)</b> = " & sBuilder.ToString() & "<br>"
' Try a different encoding
data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(strInput))
' Loop through each byte of the hashed data
' and format each one as a hexadecimal string.
sBuilder.Length = 0
For i = 0 To data.Length - 1
sBuilder.AppendFormat("{0:x2}", data(i))
Next i
lblResponse.Text &= "<b>$20.00 (UTF8)</b> = " & sBuilder.ToString() & "<br>"
Catch ex As Exception
lblErrorMessage.Text = ex.ToString()
End Try
String concatenation is . in PHP not + as in VB.Net. Thus, '1C9BRPS3TN85I2ULE5FP' + '20.00' won't result in '1C9BRPS3TN85I2ULE5FP20.00'in PHP.
Edit: VB.net's Real string concatenation is & but since the term visual basic is used, + sign can do the same as long as mathematical interpretation is meaningless.
So to be on the safe side, use &.
Related
I am trying to calculate in PHP. When I try to do that I can see that the result is mostly wrong.
The script I am using is the following:
$newrate = 1 / $rate["rate"];
echo '1 /'. $rate["rate"]. ' = '.$newrate;
The result I get is the following:
1 /1.0867 = 1
1 /117.01 = 0.0085470085470085
1 /1.9558 = 1
1 /27.534 = 0.037037037037037
1 /7.4589 = 0.14285714285714
1 /1.0867 should be 0.92021717125 and not 1.
I can reproduce this step by adding the following line to my script:
$rate["rate"] = 1.0867;
When I run the script the result is still 1. When I change my script like:
$newrate = 1 / 1.0867;
echo '1 / 1.0867 = '.$newrate;
I get a correct result. The output is then: 0.92021717125.
Does someone know what is wrong with this script? What is the reason that my script is making incorrect calculations?
Update 1:
Here is my full script:
<?php
$XML=simplexml_load_file("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml");
foreach($XML->Cube->Cube as $rat)
{
foreach($rat as $rate)
{
$newrate = '1' / $rate["rate"];
echo '1 /' . $rate["rate"] . ' = ' . $newrate;
echo '<br /><br />';
}
}
?>
I think there is something wrong with your example. I tested exactly what you described and works as expected.
<?php
$rate = [];
$rate["rate"] = "1.0867";
$newrate = 1 / $rate["rate"];
echo '1 / ' . $rate["rate"] . ' = ' . $newrate;
// 1 / 1.0867 = 0.92021717125242
You can see it running here
https://repl.it/#thiagodamata/NeighboringPeachpuffArchitect
Probably, you are using "," instead of "." when sending the number.
PHP cast the number only until it hits something unexpected. So "1,0867" is cast to 1. It is a classic problem when dealing with numbers in different formats, considering different languages.
<?php
// simulating the "," error
$rate["rate"] = "1,0867";
$newrate = 1 / $rate["rate"];
echo '1 / ' . $rate["rate"] . ' = ' . $newrate;
// 1 / 1,0867 = 1
Take a look in this thread about how to cast the number from different languages masks PHP: Locale aware number format and take a deeper look into the PHP function number-format https://www.php.net/manual/en/function.number_format.php
Update - After getting the full code example
Looking to your full code becomes more clear the problem. The var that you are getting in the loop it is a SimpleXmlElement, not a string. So, SimpleXmlElement is printed as the "1.0867" but it is not its real value.
To make the SimpleXmlElement cast to float properly, you need to use the cast function.
<?php
$XML=simplexml_load_file("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml");
foreach($XML->Cube->Cube as $rat)
{
foreach($rat as $rate)
{
print(var_dump($rate["rate"]));
/*
object(SimpleXMLElement)#7 (1) {
[0]=>
string(6) "1.0867"
}
*/
print("class = [" . get_class($rate["rate"]) . "]\n");
// class = [SimpleXMLElement]
print("as string = [" . $rate["rate"] . "]\n");
// as string = [1.0867]
print("without cast = [" . (1 * $rate["rate"]) . "]\n");
// without cast = [1]
$a = (float)($rate["rate"]);
print("with cast = [" . ($a) . "]\n");
// with cast = [1.0867]
print(serialize($a));
//d:1.0867;
$newrate = '1' / $a;
echo '1 / ' . $a . ' = ' . $newrate . "\n";
// 1 / 1.0867 = 0.92021717125242
echo '<br /><br />';
exit();
}
}
?>
You can see this running here:
https://repl.it/#thiagodamata/FuchsiaLightheartedPrintablecharacter
Just printing the value of a var does not always give you the real value of some object. There are other functions like var_export https://www.php.net/manual/en/function.var-export.php, var_dump https://www.php.net/manual/en/function.var-dump.php and serialize that may help you to see the real value of the vars.
Calculations are fine, and correct
You've not taken into account implicit type casting in PHP. Try this:
<?php
print "integer divided by float = " . (1 /1.0867) . "\n"; // returns 0.9202171712524
print "Integer divided by string = " . ((1/"1.0867") . "\n"; // returns 1
You are expecting PHP to know what your intention is when you throw a tring into an arithmetic operation - that's not how PHP works.
Just because it is dynamically typed doesn't mean you don't need to be careful with your data types.
print (1/(float)$rate['rate'];
try cast all values as a float
echo 1.0 / (float) $rate['rate'];
I need to print some numbers in a sequence with + and - between them. However, I don't know beforehand which number is going to be positive and which is going to be negative. Currently, I echo them like this:
echo "$a + $b + $c + $d + $e + $f";
Let's say the values of $a to $f are all positive. I will get something like: 5 + 10 + 12 + 18 + 9 + 7.
However, if some of the values are negative, I will get something like 5 + -10 + 12 + -18 + 9 + - 7. The ideal output in this case would have been 5 - 10 + 12 - 18 + 9 - 7.
Please not that I don't want to calculate the final result of addition or subtraction. I just want to print it all on the webpage with correct signs.
I could do so by writing 6 nested if() blocks but that seems like a lot of work and doing it every time will be error prone. Is there anything clever that I can do to output the right sign.
The easiest way would be to correct the operator appearance in the final string:
$s = '5 + -10 + 12 + -18 + 9 + - 7'; // result of interpolation or concatenation
$s = str_replace('+ -', '- ', $s);
// => "5 - 10 + 12 - 18 + 9 - 7"
If this is possible for you, this is as fast as it gets -- no looping (in php), no treating each number one at a time with a conditional. If you loop anyway, I'd recommend #Phils suggestion with array_reduce -- functional style php -- adapted to your needs.
Need to check for each variable manually like this:
echo "$a " . ($b < 0 ? " - " . abs($b) : " + $b") . ($c < 0 ? " - " . abs($c) : " + $c") . ($d < 0 ? " - " . abs($d) : " + $d") . ($e < 0 ? " - " . abs($e) : " + $e") . ($f < 0 ? " - " . abs($f) : " + $f");
you can use php sprintf function.
function formatNum($num){
return sprintf("%+d",$num);
}
or
function formatNum($num) {
$num = (int) $num; // or (float) if you'd rather
return (($num >= 0) ? '+' : '-') . $num; // implicit cast back to string
}
for more detail please read it :- http://php.net/manual/en/function.sprintf.php
try this
$a = 10;
$b=-20;
$text = $a." ".$b;
$text= str_replace(" ", "+", $text);
echo $text;
OUTPUT
10+-20
Put the numbers in an array and use array_reduce to create the string
$numbers = [5, -10, 12, -18, 9, -7];
$first = array_shift($numbers);
echo array_reduce($numbers, function($str, $num) {
return $str . sprintf(' %s %d', $num < 0 ? '-' : '+', abs($num));
}, $first);
Demo ~ https://eval.in/1034635
This way you can handle an arbitrary amount of numbers without duplicating logic everywhere.
I'm trying to read data from my online mySQL server using WinHttpRequest in VBA.
Dim objHTTP As New WinHttp.WinHttpRequest
With objHTTP
.Open "POST", "http://www.dname.com/ruski/php/getNewestPID.php", True
.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded; charset=""UTF-8"""
.Send "PID=" & lngPID
.WaitForResponse
Debug.Print .ResponseText
End With
<?php
$PID = $_POST['PID'];
require_once ('config.php');
if(!$PID>0){
die("##### Error: getNewestPID failed - PID='" . $PID . "' #####");
}
$phrases = mysql_query("SELECT * FROM phrases WHERE (PID > '$PID')");
if(!$phrases){
die("##### Error: getNewestPID SELECT failed - PID=" . $PID . " - " . mysql_error() . " #####");
}
mysql_close($db);
echo "data=";
while($row = mysql_fetch_array($phrases)) {
echo $row[0] . "|" . $row[1] . "|" . $row[2] . "|" . $row[3];
}
?>
All works well, but cyrillic text is returned like:
data=21361|105||Ð?алÑ?Ñ?ик игÑ?аеÑ? на ÑкÑ?ипке в Ñвоей комнаÑ?Ð
My db uses UTF-8 Unicode. I know cyrillic works in tables and forms, but views junk in the VB editor.
I tried this:
Set FileStream = CreateObject("ADODB.Stream")
FileStream.Open
FileStream.Type = 1 'Binary
FileStream.Write objHTTP.ResponseBody
FileStream.Position = 0
FileStream.Type = 2 'adTypeText
FileStream.Charset = "Windows-1251" ' https://msdn.microsoft.com/en-us/library/ms526296(v=exchg.10).aspx
strText = FileStream.ReadText
FileStream.Close
ending up with junk in the record:
Мальчик играет на скрипке в своей комнате.
The best result is with:
mb_convert_encoding($row[3], "Windows-1251", "UTF-8")
Ìàëü÷èê èãðàåò íà ñêðèïêå â ñâîåé êîìíàòå.
This is not very elegant but it worked for me when I had similar issues. It is simply a function that will manually go from 1251 into Unicode. This one works for Russian and Ukrainian but according to which language you are working with there may be different characters and you would need to add them to the if statement. Also consider adding an else if that throws a question mark in case the character you are looking for is not found.
Public Function AsciitoUni(base_cell As String) As String
AsciitoUni = ""
For i = 1 To Len(base_cell)
Dim s As String
Dim u As Integer
Dim a As Integer
s = Mid(base_cell, i, 1)
a = Asc(s)
If (a <= 127) Then
u = a
ElseIf (a >= 192) And (a <= 255) Then
u = a + 848
ElseIf (a = 184) Then
u = 1105
ElseIf (a = 186) Then
u = 1108
ElseIf (a = 179) Then
u = 1110
ElseIf (a = 191) Then
u = 1111
ElseIf (a = 168) Then
u = 1025
ElseIf (a = 170) Then
u = 1028
ElseIf (a = 178) Then
u = 1030
ElseIf (a = 175) Then
u = 1031
ElseIf (a = 185) Then
u = 8470
End If
AsciitoUni = AsciitoUni & ChrW(u)
Next
End Function
I am converting the following python into php
the aim is to remove scores from a string like "Liverpool 1 v 0 Everton"
home, away = event_data.get("desc").split(' v ')
# remove scores from event desc
if home.rsplit(' ', 1)[1].isdigit() and away.split(' ', 1)[0].isdigit():
event_name = home.rsplit(' ', 1)[0] + " v " + away.split(' ', 1)[1]
in php so far
$nameArray = explode(' v ', $value['name']);
$home = $nameArray[0];
$away = $nameArray[1];
$event_name = $home . ' v ' . $away;
im struggling with the stipping the scores, any tips?
Using preg_repalce in PHP you can replace digits around " v ":
$str = "Liverpool 1 v 0 Everton";
$event_name = preg_replace('/\h+\d+\h+v\h+\d+\h+/', ' v ', $str);
echo $event_name . "\n";
//=> Liverpool v Everton
<?php
$number1 = 1;
$number2 = 2;
echo $number1.' + ' . $number2. ' = '.$number1+$number2;
?>
See the above program. It is giving output as 3. Why not it is giving output as:
1 + 2 = 3
+ and . have the same precedence.
echo $number1.' + ' . $number2. ' = '.($number1+$number2);
The operations are applied in order. I.e:
echo $number1.' + ' . $number2. ' = '.$number1+$number2;
Becomes:
echo '1 + 2 = '.$number1+$number2;
Becomes:
echo '1 + 2 = 1'+$number2;
Since this is addition PHP will convert the string to an int which gives 1.
So the final expression is:
echo 1 + 2;//Prints 3
You can indicate which operations to perform together using brackets:
echo $number1.' + ' . $number2. ' = '.($number1+$number2);
your desired output :-
<?php
$number1 = 1;
$number2 = 2;
echo $number1.'+ ' . $number2.'='.($number1+$number2);
?>