История действительно не длинная. Я пытался выполнить одну из своих задач, когда понял, что существует странное поведение декодирования строки base64 в .NET C#. Вы знакомы с этой функцией, верно?
byte[] bytes = Convert.FromBase64String(text);
И вот проблема: когда вы хотите использовать свой закодированный текст как часть некоторого URL-адреса, вы хотите избежать некоторых символов, разрешенных в base64: «+», «/» и «=». Обычной практикой является замена «+» на «-», «/» на «_» и удаление всех знаков равенства с конца декодируемой строки. Вы можете погуглить процесс кодирования, я просто скажу, что знак равенства представляет собой «пробел» в декодируемой строке. Кодировка base64 занимает каждые 3 байта (каждые 3 символа) и создает для них 4 символа ASCII. Другими словами: если ваша исходная строка содержит количество символов, которое можно разделить на 3 без остатка, в конце не будет знаков равенства. Но для других случаев будет.
Было бы очень полезно, если бы функция .NET сама восстанавливала знаки равенства, но этого не происходит:
[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(“abcd”)) // -> YWJjZA== $test = "YWJjZA" [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($test)) // -> Invalid length for a Base-64 char array or string. $test = "YWJjZA==" [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($test)) // -> abcd
То же самое для С#. Если вы хотите использовать закодированную строку как часть URL-адреса, вы делаете что-то вроде этого:
var bytes = Encoding.UTF8.GetBytes(source); var encodedUrlFriendly = Convert.ToBase64String(bytes).TrimEnd(‘=’).Replace(‘+’, ‘-’).Replace(‘/’, ‘_’);
Теперь вы хотите восстановить исходную строку на сервере (или в любом другом месте). Я не претендую на идеальное решение, но это может сэкономить вам время:
encoded = encoded.Replace(‘-’, ‘+’).Replace(‘_’, ‘/’); var d = encoded.Length % 4; if (d != 0) { encoded = encoded.TrimEnd(‘=’); encoded += d % 2 > 0 ? “=” : “==”; } byte[] bytes = Convert.FromBase64String(encoded); var decoded = Encoding.UTF8.GetString(bytes);
Надеюсь, это поможет кому-то.
p.s.: Команда .NET, пожалуйста, исправьте это наконец: D