javac#base64encodehttpserverutility

Base64 Encoding in Java vs HttpServerUtility.UrlTokenEncode in C#


I'm having a trouble while I tried to encode a String in Java.

I have the follwing code in C#, and the string Bpz2Gjg01d7VfGfD8ZP1UA==, when I execute C# code I'm getting:

QnB6MkdqZzAxZDdWZkdmRDhaUDFVQT090

public static void Main(string[] args)
{
    string strWord = "Bpz2Gjg01d7VfGfD8ZP1UA==";
    byte[] encbuff = Encoding.UTF8.GetBytes(strWord);
    string strWordEncoded = HttpServerUtility.UrlTokenEncode(encbuff);
    Console.WriteLine(strWordEncoded);
}

I'm trying to replicate the previous code in Java, in the first attempt I used the javax.xml.bind.DatatypeConverter Class:

public static void main(String[] args) {
    String strWord = "Bpz2Gjg01d7VfGfD8ZP1UA==";
    byte[] encbuff = strWord.getBytes(StandardCharsets.UTF_8);
    String strWordEncoded = DatatypeConverter.printBase64Binary(encbuff);
    System.out.println(strWordEncoded);
}

But I'm getting the following String ( missing the last zero compared to C# string):

QnB6MkdqZzAxZDdWZkdmRDhaUDFVQT09

In my second attempt I used the BouncyCastle Base64 encoder:

public static void main(String[] args) {
   String strWord = "Bpz2Gjg01d7VfGfD8ZP1UA==";
   byte[] encbuff = strWord.getBytes(StandardCharsets.UTF_8);
   String strWordEncoded = new String(Base64.encode(encbuff));
   System.out.println(strWordEncoded);
}

But I'm getting the exact same previous String( still missing the last zero):

QnB6MkdqZzAxZDdWZkdmRDhaUDFVQT09

Does anyone know what may be happening?


Solution

  • I found a solution based on the comments made to me, basically I look at the source code of the method in the Reference Source of Microsoft.

    Then I translated the C# code to Java code, and it looks like this:

    public static String UrlTokenEncode(byte[] input) {
         try {
             if (input == null) {
             return null;
             }
    
             if (input.length < 1) {
                 return null;
             }
    
             String base64Str = null;
             int endPos = 0;
             char[] base64Chars = null;
    
             base64Str = Base64.toBase64String(input);
             if (base64Str == null) {
                 return null;
             }
    
             for (endPos = base64Str.length(); endPos > 0; endPos--) {
                 if (base64Str.charAt(endPos - 1) != '=') {
                     break;
                 }
             }
    
             base64Chars = new char[endPos + 1];
             base64Chars[endPos] = (char) ((int) '0' + base64Str.length() - endPos);
             for (int iter = 0; iter < endPos; iter++) {
                 char c = base64Str.charAt(iter);
                  switch (c) {
                     case '+':
                         base64Chars[iter] = '-';
                         break;
                     case '/':
                         base64Chars[iter] = '_';
                         break;
                     case '=':
                         base64Chars[iter] = c;
                     break;
                     default:
                         base64Chars[iter] = c;
                     break;
                 }
              }
             return new String(base64Chars);
         } catch (Exception e) {
             return null;
         }
    }
    

    Finally I tested the method and I got the desire output:

    public static void main(String[] args) {
       String strWord = "Bpz2Gjg01d7VfGfD8ZP1UA==";
       byte[] encbuff = strWord.getBytes(StandardCharsets.UTF_8);
       String strWordEncoded = UrlTokenEncode(encbuff);
    }
    

    M2NIclh4eEwxRGp2MEsyeFc0SHVDZz090