How to convert code from C# to PHP
I know you're hoping for someone who had experience but in case no one comes forward...
You might consider just copy and pasting the code into a PHP script and checking what breaks. Write a parser to fix that, run it across the entire script, and see what's the next thing that breaks. Continue until the script functions as expected.
If you're not using any of the more involved .Net classes I can't imagine you'll have too much trouble.
Converting Csharp to PHP with cs2php
According to @Magnus Eriksson comments, I'll try to rewrite my code and convert manually
Converting C# function to PHP
At first glance, this seems to be an XOR cipher. The one string provided is the key, and the other is a string which has been XOR'd by the key once before. XOR'ing it again with the key results in getting back the original string.
I would try to reimplement the code instead of copying it word for word, because it's not particularly well written (unless I am mistaken about the intent of the C# code, this can be rewritten in a much more readable 3 or 4 lines, without using goto, etc). There seem to be PHP examples out there on this type of thing.
Convert C# code to PHP
I am no encryption expert, but this should be working example...
# original C# code
# private static readonly byte[] IV = new byte[8] { 240, 3, 45, 29, 0, 76, 173, 59 };
# public string Decrypt(string encryptedData,string key)
# {
# encryptedData = HttpUtility.UrlDecode(encryptedData);
# byte[] buf = Convert.FromBase64String(encryptedData);
# TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
# MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
# des.Key = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key));
# des.IV = IV;
# return Encoding.ASCII.GetString(
# des.CreateDecryptor().TransformFinalBlock(
# buf,
# 0,
# buf.Length
# )
# );
# }
# }
// packs array into bytestring
function pack_array($a) {
$out = null;
foreach ($a as $i) { $out .= chr(ord(substr($i,0,1))); }
var_dump(($out));
return $out;
}
class Sample {
public static $IV = array( 240, 3, 45, 29, 0, 76, 173, 59 );
public static $key = 's3cr3tk3yl0ng1n4ph';
// 3des encryption
public static function Encrypt($data) {
$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
$ks = mcrypt_enc_get_key_size($td);
// create key
$key = substr(md5(self::$key), 0, $ks);
// pack IV
$IVPacked = pack_array(self::$IV);
mcrypt_generic_init($td, $key, $IVPacked);
$encryptedData = mcrypt_generic($td, $data);
mcrypt_generic_deinit($td);
$encryptedData = base64_encode($encryptedData);
$encryptedData = urlencode($encryptedData);
return $encryptedData;
}
// 3des decryption
public static function Decrypt($encryptedData, $key) {
$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
$encryptedData = urldecode($encryptedData);
$encryptedData = base64_decode($encryptedData);
$key = substr(md5($key), 0, mcrypt_enc_get_key_size($td));
$IVPacked = pack_array(self::$IV);
mcrypt_generic_init($td, $key, $IVPacked);
$decryptedData = mdecrypt_generic($td, $encryptedData);
mcrypt_generic_deinit($td);
return $decryptedData;
}
}
// __main__
$data = "methodname=GetClientшђшђ";
var_dump($data);
//var_dump(unpack_str($data, strlen($data)));
$encryptedData = Sample::Encrypt($data);
//var_dump(bin2hex(Sample::$IV));
var_dump (bin2hex($encryptedData));
$decryptedData = Sample::Decrypt($encryptedData, Sample::$key);
var_dump($decryptedData);
echo "\n";
Convert C# to PHP
Your arrays don't look right. ItemLines
and PaymentLines
should be arrays instead of an object containing an array.
Even though StartSale
returns them as objects, they should still be an array for the call to SaveSale
. The reason they are returned as objects is a quirk of the PHP SoapClient. What happens is, if there is just one element in the array, the SoapClient gives you an object with its properties set as the single element properties. However if there is more than one element in the array, you get an array of objects instead, and so is one level deeper than the result when there's only a single element. So because they are returned with no elements from StartSale
, they are given as objects instead of an empty array.
...
...
$Sale->StartSaleResult->ItemLines = array($line);
// Payment line, cash
$cash = new stdClass();
$cash->Type = 'Cash';
$cash->Qty = 1;
$cash->LineAmount = 600;
// Payment line, Change
$change = new stdClass();
$change->Type = 'Change';
$change->Qty = 1;
$change->LineAmount = -100;
$Sale->StartSaleResult->PaymentLines = array($cash, $change);
Also depending on what the WSDL looks like, you may need to pass an associative array as the parameters, with keys as sale
and key
(according to the WSDL), instead of passing two separate arguments:
$response = $client->SaveSale(array('sale' => $Sale->StartSaleResult, 'key' => 'xxxxxxxx'));
Change sale
and key
to whatever the WSDL defines them as.
Convert C# Code to PHP Code to extract one xml tag from html
the translation of
private static String CutOutXML(string resp)
{
var url = resp.Substring(resp.IndexOf("<div>") + "<div>".Length);
url = url.Substring(0, url.IndexOf("</div>"));
return url;
}
would be
function CutOutXML(string $resp):string
{
$url = substr($resp,strrpos($resp,'<div>')+ strlen('<div>'));
$url = substr($url,0, strrpos($url,"</div>"));
return $url;
}
however as the other comments say there are much better ways of doing what you appear to be trying to do
eg
$matches = [];
preg_match('/<div>(.*)<\/div>/', $resp, $matches);
print_r($matches);
Convert simple encryption method in c# to php
In the C# code, the mode is not explicitly specified, so that the CBC mode is used by default. In the PHP code, however, the ECB mode is applied, which must be changed into the CBC mode.
In the C# code newEncKey
is used as key, which is 16 bytes in size and is implicitly extended to 24 bytes (3 times the TripleDES block size of 8 bytes) by appending the first 8 bytes at the end (this corresponds to 2TDEA). This must be done explicitly in the PHP code. Also remove the MD5 digest, as it's not used in C# code:
$byte = mb_convert_encoding($key, 'ASCII');
//$desKey = md5(utf8_encode($byte), true);
$desKey = $byte . substr($byte, 0, 8);
In the C# code newEncKey
is also used as IV, of which implicitly only the first 8 bytes are applied (1 times the TripleDES block size). In the PHP code the shortening of the IV must be done explicitely, e.g. with
$desIV = substr($byte, 0, 8);
The IV must be passed as 5th parameter in mcrypt_encrypt
:
$encData = mcrypt_encrypt('tripledes', $desKey, $data, 'cbc', $desIV);
The C# code uses PKCS7 padding by default, so this is consistent with the padding of the PHP code.
With these changes, the PHP code produces the same result as the C# code.
For security reasons, key/IV pairs may not be used more than once. The logic used here (generation of the IV from the key) therefore requires a new key for each encryption. Furthermore mcrypt_encrypt
is deprecated, a better alternative is openssl_encrypt
, which also uses PKCS7 padding by default.
Converting C# code to php encoding issue
The solution, updated:
$a = "SF0D9G9SGGF0gdsfg976590";
$a = mb_convert_encoding($a, "UTF-16LE");
$a = md5($a, true);
$res = '';
for($i=0; $i<16; $i+=2) {
// System.Text.Encoding.Unicode.GetString(byteHashValue) replaces invalid characters to 0xfffd ('я')
// while PHP to 0x003d ('?') or empty string. So replace them like C# does
$a2 = mb_convert_encoding($a[$i].$a[$i+1], "UTF-16LE","UTF-16LE"); // check if this is invalid UTF-16 character
if(strlen($a2)==0 || $a[$i]!=$a2[0]) {
// replace invalid UTF-16 character with C# like
$v = 0xfffd;
}
else {
// prepare a word (UTF-16 character)
$v = ord($a[$i+1])<<8 | ord($a[$i]);
}
// print each word without leading zeros as C# code does
$res .= sprintf("%x",$v);
}
echo($res);
Related Topics
Parsing HTML to Get Script Variable Value
Return Contents of a Std::Wstring from C++ into C#
Fixing Gridview Header While Scrolling
How to Create a Progress Bar with Rounded Corners in iOS Using Xamarin.Forms
How to Add a Custom View Dynamically to a View in Visual Studio for MAC C#
Capturing Webpage as Image in C#, Ensuring JavaScript Rendered Elements Are Visible
How to #Define Constant on a Solution Basis
With C# Use Chrome to Covert HTML to Pdf
Insert into SQL Db a String That Contain Special Character '
Get Text Between 2 HTML Tags C#
How to Conditionally Control The Visibility of a Control in Asp.Net