E-Invoicing QR Code TLV with Base64 in C# , it only works if the company name is written in Latin letters

4.3k Views Asked by At

The attached code is working only if the company name is written in Latin letters but not working properly if the company name is in Arabic. Could anyone please advise and add the proper part to the code, I am a beginner in this field.

Tag-Length-Value (TLV) . • Code of the message type (T) - 1 Byte fixed sizes of 1 byte (2 digits). • Message value length (L) - 1 Byte fixed sizes of 1 byte (2 digits). • Message value itself. (V) - Variable (variable size) includes the result of encoding the text string into hexadecimal

Example of a TLV if the company name is written in Latin letters

String : Bobs Records3101223935000032021-12-10 01:26:44100.0015.00

Proper results: Hexadecimal: 010C426F6273205265636F726473020F3331303132323339333530303030330313323032312D31322D31302030313A32363A343404063130302E3030050531352E3030

HexToBase64: AQxCb2JzIFJlY29yZHMCDzMxMDEyMjM5MzUwMDAwMwMTMjAyMS0xMi0xMCAwMToyNjo0NAQGMTAwLjAwBQUxNS4wMA==

Decoded from Base64 format through https://www.base64decode.org :

Bobs Records 310122393500003 2021-12-10 01:26:44 100.00 15.00

=================================== Example of a TLV if the company name is written in Arabic letters:

String : شركة الأرض3101223935000032021-12-10 01:26:44100.0015.00

Improper results but don’t know where the issue is:

Hexadecimal: 010A3F3F3F3F203F3F3F3F3F020F3331303132323339333530303030330313323032312D31322D31302030313A32363A343404063130302E3030050531352E3030

HexToBase64: AQo/Pz8/ID8/Pz8/Ag8zMTAxMjIzOTM1MDAwMDMDEzIwMjEtMTItMTAgMDE6MjY6NDQEBjEwMC4wMAUFMTUuMDA=

Decoded from Base64 format through https://www.base64decode.org

???? ????? 310122393500003 2021-12-10 01:26:44 100.00 15.00

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace tlvgenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            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 decString = SallerName + VATReg + DateTimeStr + TotalAmt + VatAmt;
            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();
        }
    }
}
3

There are 3 best solutions below

1
Markus Safar On

To my knowledge Encoding.Default will return an encoding for the system's current ANSI code page. So in order to encode and decode anything else (like arabic letters) you should use Encoding.Unicode instead.

1
user17655754 On
   static string gethexstring(Int32 TagNo, string TagValue)
        {
          
            string decString = TagValue;
            byte[] bytes = Encoding.UTF8.GetBytes(decString);
            string hexString = BitConverter.ToString(bytes);

            string StrTagNo = String.Format("0{0:X}", TagNo);
            String TagNoVal = StrTagNo.Substring(StrTagNo.Length - 2, 2);

            string StrTagValue_Length = String.Format("0{0:X}", bytes.Length);
            String TagValue_LengthVal = StrTagValue_Length.Substring(StrTagValue_Length.Length - 2, 2);


            hexString = TagNoVal + TagValue_LengthVal + hexString.Replace("-", "");
            return hexString;
        }
1
lava On

You can use this classs get Correct output

public class SaudiConvertion
{

    public String getTest()
    {
        // var sellername = "Salah Hospital";
        var sellername = " الجواهري العربي";
        var vatregistration = "310122393500003";
        var timestamp = "2021-12-10 01:26:44";
        var invoiceamount = "200.00";
        var vatamoun = "125.00";
 
        return getBase64(sellername, vatregistration, timestamp, invoiceamount, vatamoun);
    }

    public String getBase64(String sellername, String vatregistration, String timestamp, String invoiceamount,
        String vatamoun)
    {
        string ltr = ((char)0x200E).ToString();
        var seller = getTlvVAlue("1", sellername);
        var vatno = getTlvVAlue("2", vatregistration);
        var time = getTlvVAlue("3", timestamp);
        var invamt = getTlvVAlue("4", invoiceamount);
        var vatamt = getTlvVAlue("5", vatamoun);
        var result = seller.Concat(vatno).Concat(time).Concat(invamt).Concat(vatamt).ToArray();
        Console.WriteLine(result);
        ;
        Console.WriteLine(result.ToString());
        ;
        var output = Convert.ToBase64String(result);
        Console.WriteLine(output);
        return output;
    }



    public byte[] getTlvVAlue(String tagnums, String tagvalue)
    {
        string[] tagnums_array = { tagnums };
        var tagvalue1 = tagvalue;
 
        var tagnum = tagnums_array.Select(s => Byte.Parse(s)).ToArray();
       


        var tagvalueb = Encoding.UTF8.GetBytes(tagvalue1);
        string[] taglengths = { tagvalueb.Length.ToString() };
        var tagvaluelengths = taglengths.Select(s => Byte.Parse(s)).ToArray();
        var tlvVAlue = tagnum.Concat(tagvaluelengths).Concat(tagvalueb).ToArray();


        return tlvVAlue;
    }
}

Call like this

      var saudiConvertion = new SaudiConvertion();
        
        var test = saudiConvertion.getTest();

        Console.WriteLine(test);

Output Base64:-

AR4g2KfZhNis2YjYp9mH2LHZiiDYp9mE2LnYsdio2YoCDzMxMDEyMjM5MzUwMDAwMwMTMjAyMS0xMi0xMCAwMToyNjo0NAQGMjAwLjAwBQYxMjUuMDA=

You can use qrcodelib from nugetpackage to make qrcode And the output may like this Arabic enter image description here

The Scanned result may like this:Zatka app from Playstore vat zatka enter image description here

Scanned in E-invoice from playstore

enter image description here latin letter English:

enter image description here Base64 :

AQ5TYWxhaCBIb3NwaXRhbAIPMzEwMTIyMzkzNTAwMDAzAxMyMDIxLTEyLTEwIDAxOjI2OjQ0BAYyMDAuMDAFBjEyNS4wMA==

the scanned result like this: enter image description here

Base64 to Image Nuget Package qrcoder document

VB.net c# same too.

   Dim qrcode As GenerateQr = New GenerateQr()
      var bitmapp=   qrcode.getQrBitmap(base64string)

 Dim qrcode As GenerateQr = New GenerateQr()
      
        Dim getBase64 As String = saudiConvertion.getBase64(company.name, company.GST,
                                                            billDetail.KotGModel.dates,
                                                            billDetail.KotGModel.totalAmount,
                                                            billDetail.KotGModel.vattax)
        Dim getQrBitmap As Bitmap = qrcode.getQrBitmap(getBase64)
        Dim pictureBox As PictureBox = New PictureBox()
        pictureBox.Image = getQrBitmap