Кодирование Base64 в Java против HttpServerUtility.UrlTokenEncode в C # - PullRequest
0 голосов
/ 29 марта 2019

У меня проблемы при попытке кодировать String в Java.

У меня есть следующий код на 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

Кто-нибудь знает, что может происходить?

Ответы [ 2 ]

1 голос
/ 29 марта 2019

Я посмотрел код платформы .NET.UrlTokenEncode фактически удаляет любые дополнительные = символы заполнения с конца строки base64 и заменяет их количеством символов заполнения, так что либо 0, 1, либо 2.Это то, что вызывает дополнительные 0 в конце вашей строки.Так что учтите: метод HttpServerUtility.UrlTokenEncode НЕ является простым кодировщиком Base64.На самом деле он использует Convert.ToBase64String внутри для обычной кодировки и добавляет еще несколько сверху (см. Мои комментарии по этому вопросу).Если вам нужно создать эту точную строку, вам нужно будет реализовать те же изменения в Java поверх обычной кодировки base64.

0 голосов
/ 30 марта 2019

Я нашел решение на основе комментариев, сделанных мной, в основном я смотрю на исходный код метода в Справочном источнике 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

...