Кодирование Base64 в Java против HttpServerUtility.UrlTokenEncode в C#
У меня проблемы, когда я пытался закодировать 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
Кто-нибудь знает, что может происходить?
2 ответа
Я нашел решение на основе комментариев, сделанных мной, в основном я смотрю на исходный код метода в справочном источнике 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
Я посмотрел на код.NET Framework. UrlTokenEncode
на самом деле удаляет любые дополнительные =
символы заполнения с конца строки base64 и заменяют их количеством символов заполнения, так что либо 0
, 1
, или же 2
, Это то, что вызывает дополнительный 0
в конце вашей строки. Так что знайте: HttpServerUtility.UrlTokenEncode
Метод НЕ является простым кодировщиком Base64. Это на самом деле использует Convert.ToBase64String
внутренне для обычного кодирования и добавляет еще несколько сверху (см. мои комментарии по этому вопросу). Если вам нужно создать эту точную строку, вам нужно будет реализовать те же изменения в Java поверх обычной кодировки base64.