I have a code will decodebase64
the public key and then add it in QR TLV code, but when I add it in QR code the format is different than in PHP, and not same as I need it!
the Decoded64 Public key in C#:
0V0*�H�=+�
Ba���L;�-z�_g&���u�$��½k9�-��տ�.��A�ڇ)�1��_�B�x�i�;��'�
the what I need it like this:
X0V0*H=+�
B�a`L;-z_g&u$½k9-տ.Aڇ)1_Bxi;'
my C# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace tlvgenerator
{
class Program
{
static void Main(string[] args)
{
static string Base64Decode(string base64EncodedData)
{
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
string base64 = "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYYMMoOaFYAhMO/steotfZyavr6p11SSl wsK9azmsLY7b1b+FLhqMArhB2dqHKboxqKNfvkKDePhpqjui5hcn0Q==";
Console.WriteLine("Encoded String = " + base64);
var original = Base64Decode(base64);
byte[] bytes = Encoding.Default.GetBytes(original);
original = Encoding.UTF8.GetString(bytes);
Console.WriteLine("Decoded String = " + original);
string SallerName = gethexstring(1, "Bobs Records"); //Tag1
string VATReg = gethexstring(2, "310122393500003"); //Tag2
string DateTimeStr = gethexstring(3, "2022-04-25 15:30:00"); //Tage3
string TotalAmt = gethexstring(4, "10000.00"); //Tag4
string VatAmt = gethexstring(5, "150.00"); //Tag5
string PK = gethexstring(6, original); //Tag6
string decString = SallerName + VATReg + DateTimeStr + TotalAmt + VatAmt + PK;
Console.WriteLine(decString);
Console.WriteLine(HexToBase64(decString));
Console.Read();
}
static string gethexstring(Int32 TagNo, string TagValue)
{
string StrTagNo = String.Format("0{0:X}", TagNo);
String TagNoVal = StrTagNo.Substring(StrTagNo.Length - 2, 2);
string StrTagValue_Length = String.Format("0{0:X}", TagValue.Length);
String TagValue_LengthVal = StrTagValue_Length.Substring(StrTagValue_Length.Length - 2, 2);
string decString = TagValue;
byte[] bytes = Encoding.Default.GetBytes(decString);
string hexString = BitConverter.ToString(bytes);
hexString = TagNoVal + TagValue_LengthVal + hexString.Replace("-", "");
return hexString;
}
static string gethexDec(Int32 TagValue)
{
string hxint = String.Format("0{0:X}", TagValue);
return hxint.Substring(hxint.Length - 2, 2);
}
public static string HexToBase64(string strInput)
{
try
{
var bytes = new byte[strInput.Length / 2];
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(strInput.Substring(i * 2, 2), 16);
}
return Convert.ToBase64String(bytes);
}
catch (Exception)
{
return "-1";
}
}
private string StringToHex(string hexstring)
{
StringBuilder sb = new StringBuilder();
foreach (char t in hexstring)
{
//Note: X for upper, x for lower case letters
sb.Append(Convert.ToInt32(t).ToString("x"));
}
return sb.ToString();
}
}
}
the QR output which is not same I want it:
AQxCb2JzIFJlY29yZHMCDzMxMDEyMjM5MzUwMDAwMwMTMjAyMi0wNC0yNSAxNTozMDowMAQIMTAwMDAuMDAFBjE1MC4wMAZUMFYwEAYHKu+/vUjvv709AgEGBSvvv70EAAoDQgAEYe+/vQzvv73vv71gCEw777+9LXrvv71fZybvv73vv73vv71177+9JO+/ve+/vcK9aznvv70t77+977+91b/vv70uGu+/vQLvv71B77+92ocp77+9Me+/ve+/vV/vv71C77+9eO+/vWnvv70777+977+9Fyfvv70=
the correct expected QR code like in PHP:
AQxCb2JzIFJlY29yZHMCDzMxMDEyMjM5MzUwMDAwMwMTMjAyMi0wNC0yNSAxNTozMDowMAQIMTAwMDAuMDAFBjE1MC4wMAZYMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYYMMoOaFYAhMO/steotfZyavr6p11SSlwsK9azmsLY7b1b+FLhqMArhB2dqHKboxqKNfvkKDePhpqjui5hcn0Q==
What is the wrong in C# code and how can I solve the issue? I thought was from UTF8 but it's not!
MFY...cn0Q==
is a DER encoded public EC key in X.509/SPKI format after Base64 encoding. This is corrupted during UTF8 encoding in Base64Decode()
, which is shown in the replacement characters 0xEFBFBD of the result.
Also the use of the default encoding in Encoding.Default
should be avoided, instead the encoding should be specified concretely.
A possible fix is:
string base64 = "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYYMMoOaFYAhMO/steotfZyavr6p11SSlwsK9azmsLY7b1b+FLhqMArhB2dqHKboxqKNfvkKDePhpqjui5hcn0Q==";
string sallerName = GetHexString(1, Encoding.UTF8.GetBytes("Bobs Records")); //Tag1
string vatReg = GetHexString(2, Encoding.UTF8.GetBytes("310122393500003")); //Tag2
string dateTimeStr = GetHexString(3, Encoding.UTF8.GetBytes("2022-04-25 15:30:00")); //Tag3
string totalAmt = GetHexString(4, Encoding.UTF8.GetBytes("10000.00")); //Tag4
string vatAmt = GetHexString(5, Encoding.UTF8.GetBytes("150.00")); //Tag5
string pk = GetHexString(6, Convert.FromBase64String(base64)); //Tag6
string decString = sallerName + vatReg + dateTimeStr + totalAmt + vatAmt + pk;
Console.WriteLine(HexToBase64(decString));
with
static string GetHexString(int tagNo, byte[] tagValue)
{
string strTagNo = string.Format("0{0:X}", tagNo);
string tagNoVal = strTagNo.Substring(strTagNo.Length - 2, 2);
string strTagValueLength = string.Format("0{0:X}", tagValue.Length);
string tagValueLengthVal = strTagValueLength.Substring(strTagValueLength.Length - 2, 2);
return tagNoVal + tagValueLengthVal + BitConverter.ToString(tagValue).Replace("-", "");
}
Here in GetHexString()
the encoding was moved outside, so that the method can be used for all tags independently of the input encoding.
This fix gives the expected result.