Я пытаюсь base64 кодировать огромный входной файл и заканчивать текстовым выходным файлом, и я пытаюсь выяснить, возможно ли кодировать входной файл поэтапно, или мне нужно кодировать весь вещь сразу.
Это будет сделано на AS/400 (iSeries), если это имеет значение. Я использую свою собственную процедуру кодирования base64 (написанную в RPG), которая отлично работает, и если бы это был не случай ограничений по размеру, было бы хорошо.
Невозможно бит-бит-бит , но 3 байта за раз, или кратные 3 байта в момент выполнения будут !.
Другими словами, если вы разделите свой входной файл на «куски», размер (ы) которого (являются) кратными 3 байтам, вы можете кодировать куски отдельно и объединять полученные фрагменты, закодированные B64 (в соответствующем orde, из Обратите внимание, что последний chuink не должен быть точно кратным 3 байтам в зависимости от значения по модулю 3 его соответствующего значения B64 будет иметь несколько из этих дополняющих символов (как правило, знак равенства), но это нормально , так как это будет единственной частью, которая имеет (и нуждается) такое дополнение.
В направлении декодирования это та же идея, за исключением того, что вам нужно разбить данные, закодированные B64, в кратном размере 4 байта. Декодируйте их параллельно/индивидуально по желанию и повторно отделите исходные данные, добавив декодированные части вместе (снова в том же порядке).
<Сильный> Пример:
"File" contents =
"Never argue with the data." (Jimmy Neutron)
.
Straight encoding = Ik5ldmVyIGFyZ3VlIHdpdGggdGhlIGRhdGEuIiAoSmltbXkgTmV1dHJvbik=
Now, in chunks:
"Never argue
--> Ik5ldmVyIGFyZ3Vl
with the
--> IHdpdGggdGhl
data." (Jimmy Neutron)
--> IGRhdGEuIiAoSmltbXkgTmV1dHJvbik=
Поскольку вы видите кусок в этом порядке, 3 закодированные фрагменты равны тому, что и код, созданный для всего файла.
Декодирование выполняется аналогичным образом с произвольным размером chuncked при условии, что они кратно 4 байтам. Абсолютно не нужно иметь никакого соответствия между размерами, используемыми для кодирования. (хотя стандартизация до одного размера для каждого направления (скажем 300 и 400) может сделать вещи более однородными и удобными в управлении.
Хм, если вы сами написали преобразование base64, вы должны были заметить очевидную вещь: каждая последовательность из 3 октетов представлена четырьмя символами в base64.
Таким образом, вы можете разделить данные base64 каждые четыре символа, и будет возможно преобразовать эти куски обратно в исходные биты.
Я не знаю, как файлы символов и байтовые файлы обрабатываются в AS/400, но если у них есть обе концепции, это должно быть очень просто.
Если вы можете ответить на все эти вопросы, какие точные трудности у вас остались?
Это тривиальное усилие разбить любой заданный поток на куски.
Вы можете без проблем использовать base64 любой кусок байтов.
Проблема, с которой вы столкнулись, заключается в том, что, если вы не зададите конкретные требования к вашим кускам (кратные 3 байтам), последовательность блоков с кодировкой base64 будет отличаться от того, какой вы хотите получить.
В C # это один (неряшливый) способ сделать это лениво. Выполнение фактически отложено до тех пор, пока не будет выведена строка. Concat вызывается, поэтому вы можете делать все, что хотите, с чередующимися строками. (Если вы подключите это в LINQPad, вы увидите выход)
void Main()
{
var data = "lorum ipsum etc lol this is an example!!";
var bytes = Encoding.ASCII.GetBytes(data);
var testFinal = Convert.ToBase64String(bytes);
var chunkedBytes = bytes.Chunk(3);
var base64chunks = chunkedBytes.Select(i => Convert.ToBase64String(i.ToArray()));
var final = string.Concat(base64chunks);
testFinal.Dump(); //Вывод
final.Dump(); //Вывод
}
public static class Extensions
{
public static IEnumerable> Chunk(this IEnumerable list, int chunkSize)
{
while(list.Take(1).Count() > 0)
{
yield return list.Take(chunkSize);
list = list.Skip(chunkSize);
}
}
}
Вывод
bG9ydW0gaXBzdW0gZXRjIGxvbCB0aGlzIGlzIGFuIGV4YW1wbGUhIQ==
bG9ydW0gaXBzdW0gZXRjIGxvbCB0aGlzIGlzIGFuIGV4YW1wbGUhIQ==