c# Convert.To/FromBase64String путаница

Предполагая, что у меня есть этот метод.

private static void Example(string data)
    {
        Console.WriteLine("Initial : {0}", data);

        data = data.PadRight(data.Length + 1, '0'); 
        Console.WriteLine("Step 1 : {0}", data);

        data = data.PadRight(data.Length + 4 - data.Length % 4, '=');
        Console.WriteLine("Step 2 : {0}", data);

        byte[] byteArray = Convert.FromBase64String(data);
        string newData = Convert.ToBase64String(byteArray);
            Console.WriteLine("Step 3 : {0}", newData);
    }

Я ожидаю, что вывод с учетом входной строки «1» будет следующим

Initial : 1
Step 1 : 10
Step 2 : 10==
Step 3 : 10==

Вместо этого вывод такой.

Initial : 1
Step 1 : 10
Step 2 : 10==
Step 3 : 1w==

И я понятия не имею, почему. Я ожидал бы, что вывод будет таким же, как ввод, но это не так. Я попытался заменить

data = data.PadRight(data.Length + 1, '0'); 

с участием

data = data + "0";

Он появляется и с более длинными входными строками, например, со строками длиной 5 или 9. Он отлично работает, если я добавляю "=", но затем я превышаю лимит заполнения с помощью Convert.FromBase64String()

Итак, мой вопрос на самом деле заключается в том, что происходит и как я могу получить ожидаемый результат? Что я делаю неправильно?

Изменить: для тех, кто не понимает, почему я использую bas64, это связано с этим PHP расшифровывает данные с помощью закрытого ключа RSA


person That Homeless Guy    schedule 21.08.2014    source источник
comment
это похоже на проблему кодирования   -  person MethodMan    schedule 22.08.2014
comment
подойдет ли вам это string newData = System.Text.Encoding.Default.GetString(byteArray);   -  person MethodMan    schedule 22.08.2014
comment
@DJKRAZE: Нет, абсолютно нет. Это не имеет ничего общего с таким кодированием.   -  person Jon Skeet    schedule 22.08.2014
comment
@DJKRAZE ваше предложение привело к Step 3 : x Но дело в том, что если ввод состоит из 2 символов, и я добавляю 2 отступа =, тогда все в порядке. Также, если я добавлю несколько символов в строку, которая не является дополнением, любые добавленные символы станут w   -  person That Homeless Guy    schedule 22.08.2014
comment
@ThatHomelessGuy: Чего вы на самом деле пытаетесь достичь? Вы должны пытаться кодировать бинарные данные, используя base64... зачем вам брать строку и дополнять ее вот так?   -  person Jon Skeet    schedule 22.08.2014
comment
Я дополняю строку, потому что ¬Convert.FromBase64String¬ работает только со строками, длина которых делится на 4.   -  person That Homeless Guy    schedule 22.08.2014
comment
Мусор на входе, мусор на выходе. Каждый символ base64 кодирует 6 бит. Вы предоставляете 12 бит данных с 10, это не кратно 8. Таким образом, его можно декодировать только в один байт, 0xd7. Который закодирован как 1w==.   -  person Hans Passant    schedule 22.08.2014


Ответы (1)


По сути, не существует массива байтов, который можно было бы закодировать в 10==.

Если строка base64 заканчивается на ==, это означает, что последние 4 символа представляют только один байт. Таким образом, важны только первый символ и первые 2 бита второго символа. Глядя на таблицу Википедии, 10 означает значения:

'1' = 53  '0' = 52
110101    110100

Таким образом, кодируется байт 1101 0111, а затем последние четыре бита (0100) игнорируются. Когда вы перекодируете данные, вместо последних четырех битов используются 0, что дает:

'1' = 53  'w' = 48
110101    110000

По сути, неясно, что вы пытаетесь сделать, но если ваш ввод является частью значения в кодировке base64, это довольно странно. Код ведет себя так, как я ожидал - это просто не полезный код...

person Jon Skeet    schedule 21.08.2014
comment
Я использую base64, так как шифрую байты и преобразовываю их в шестнадцатеричную строку (для удобства транспортировки), затем я отправляю шестнадцатеричную строку в php-скрипт на веб-сервере, который преобразует шестнадцатеричный код в двоичную строку и расшифровывает их. обратно, прежде чем снова преобразовать их в текст. Все это работает до момента заполнения входов неравномерной длины. - person That Homeless Guy; 22.08.2014
comment
@ThatHomelessGuy: Какое отношение шифрование и шестнадцатеричный код имеют к base64? Если вы шифруете, результатом этого шифрования должны быть двоичные данные, а не текст, чтобы вы могли передать эти двоичные данные в Convert.ToBase64String. Если вы ожидаете, что base64 будет шифрованием, это просто не так, и его не следует рассматривать как таковое. Все еще не очень понятно, что вы делаете - вы должны показать все шаги (с чего вы начали, где вы шифруете, в основном каждое преобразование) - и поместите это в вопрос. У меня есть подозрение, что вы просто неправильно поняли назначение base64. - person Jon Skeet; 22.08.2014
comment
Я заменяю символ заполнения на /, я думаю, что неправильно понял заполнение base64. Спасибо. - person That Homeless Guy; 22.08.2014
comment
@ThatHomelessGuy: Это действительно ничего не объясняет... Еще раз, пожалуйста, дайте более подробную информацию в вопросе. - person Jon Skeet; 22.08.2014
comment
stackoverflow.com/ вопросы/25222881/ - person That Homeless Guy; 22.08.2014
comment
@ThatHomelessGuy: Ну, этот вопрос предполагает, что вы начинаете с действительной строки base64, содержащей данные для шифрования. Почему вы принимаете строку base64, а не просто массив байтов? И зачем вам нужно было бы добавлять отступы самостоятельно? Каковы входные данные для вашего метода Encrypt? Потому что, если это не уже строка base64 - если это произвольный текст - тогда это не правильный подход. Вместо этого вы должны использовать что-то вроде Encoding.UTF8.GetBytes(data). - person Jon Skeet; 22.08.2014
comment
Я попробую это решение (ранее я использовал ¬Encoding.Unicode.GetBytes(data)¬ ), но теперь мне нужно выяснить, как преобразовать двоичную строку в UTF8 в PHP. Мне указали на Base64, поскольку он, по-видимому, лучше подходит для преобразования данных без потерь с байтами, с которыми я сталкивался ранее. - person That Homeless Guy; 22.08.2014
comment
@ThatHomelessGuy: вы используете base64 для преобразования без потерь из произвольных двоичных данных в текстовые данные. Вы используете что-то вроде UTF-8 для преобразования без потерь из произвольных текстовых данных в двоичные данные. Очень важно понимать все преобразования, которые вы выполняете с вашими данными — если вы используете неподходящее преобразование, вы почти наверняка потеряете информацию. Я подозреваю, что в PHP вам просто нужно utf8_decode, кстати. . - person Jon Skeet; 22.08.2014
comment
Спасибо, я перестрою свою аутентификацию на основе информации, которую вы мне дали. Я не очень разбираюсь в PHP, и это очень сильно отражается на том, как я взаимодействую с ним. Я заблудился, пытаясь скомпрометировать PHP. О, и большое спасибо. - person That Homeless Guy; 22.08.2014
comment
¬Encoding.UTF8.GetBytes(data)¬ было идеальным решением, а ¬utf8_decode¬php — работа. Еще раз спасибо. - person That Homeless Guy; 22.08.2014
comment
Увидев ваш ответ @Jon Skeet, это имеет смысл, из исходного вопроса ОП было трудно определить, чего он действительно пытался достичь ... Я должен был сначала задать этот вопрос. - person MethodMan; 22.08.2014