Java中的Base64编码与C#中的HttpServerUtility.UrlTokenEncode

问题描述 投票:0回答:2

当我尝试用Java编码String时,我遇到了麻烦。

我在C#中有以下代码,而string Bpz2Gjg01d7VfGfD8ZP1UA ==,当我执行C#代码时,我得到:

QnB6MkdqZzAxZDdWZkdmRDhaUDFVQT090

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

我试图在Java中复制以前的代码,在第一次尝试中我使用了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);
}

但我得到以下String(与C#string相比缺少最后一个零):

QnB6MkdqZzAxZDdWZkdmRDhaUDFVQT09

在我的第二次尝试中,我使用了BouncyCastle Base64编码器:

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);
}

但我得到了完全相同的以前的String(仍然缺少最后的零):

QnB6MkdqZzAxZDdWZkdmRDhaUDFVQT09

有谁知道可能会发生什么?

java c# base64 encode httpserverutility
2个回答
1
投票

我已经看过.NET框架代码了。 UrlTokenEncode实际上从base64字符串的末尾删除任何额外的=填充符号,并用填充符号的数量替换它们,因此012。这就是在你的字符串末尾引起额外的0的原因。请注意:HttpServerUtility.UrlTokenEncode方法不是普通的Base64编码器。它实际上在内部使用Convert.ToBase64String进行常规编码,并在顶部添加更多内容(请参阅我对该问题的评论)。如果需要创建这个确切的字符串,则需要在常规base64编码的基础上在Java中实现相同的更改。


0
投票

我找到了一个解决方案,基于对我的评论,基本上我看看Reference Source of Microsoft.中方法的源代码

然后我将C#代码翻译成Java代码,它看起来像这样:

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;
     }
}

最后我测试了方法,我得到了欲望输出:

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

M2NIclh4eEwxRGp2MEsyeFc0SHVDZz090

© www.soinside.com 2019 - 2024. All rights reserved.