是否可以以块的形式对文件进行base64编码?

时间:2011-10-27 18:46:50

标签: base64

我正在尝试base64编码一个巨大的输入文件并最终得到一个文本输出文件,我试图找出是否可以逐位编码输入文件,或者我是否需要一次编码整个事物。

这将在AS / 400(iSeries)上完成,如果这有任何区别的话。我正在使用我自己的base64编码例程(用RPG编写),它运行良好,如果不是大小限制的情况,那就没问题了。

3 个答案:

答案 0 :(得分:30)

不可能 逐位 ,但一次3个字节,或者3个字节的倍数

换句话说,如果将输入文件拆分为“块”,其大小是3个字节的倍数,则可以单独对块进行编码,并将生成的B64编码块拼凑在一起(在相应的中)当然,请注意,最后一个chuink的大小不一定是3个字节的倍数,具体取决于其大小的模3值,其对应的B64值将具有一些这些填充字符(通常为等号)但是没关系,因为这将是唯一具有(并且需要)这种填充的部分。

在解码方向上,除了需要以4字节的倍数分割B64编码数据之外,它是相同的想法。根据需要并行/单独解码它们,并通过将解码的部分附加在一起来重新分割原始数据(再次以相同的顺序)。

示例:

“文件”内容= "Never argue with the data." (Jimmy Neutron)
直接编码= Ik5ldmVyIGFyZ3VlIHdpdGggdGhlIGRhdGEuIiAoSmltbXkgTmV1dHJvbik=

现在,大块:
"Never argue - > Ik5ldmVyIGFyZ3Vl
with the - > IHdpdGggdGhl
data." (Jimmy Neutron) - > IGRhdGEuIiAoSmltbXkgTmV1dHJvbik=

正如您所看到的那样,3个编码块的数量与为整个文件生成的代码相同。

解码完成类似,任意chuncked大小,只要它们是4个字节的倍数。绝对不需要在用于编码的大小之间具有任何类型的对应关系。 (尽管每个方向标准化为一个单一尺寸(比如300和400)可能会使事情更加统一,更易于管理。

答案 1 :(得分:2)

嗯,如果您自己编写了base64转换,您应该注意到显而易见的事情:每个3个八位字节的序列由base64中的4个字符表示。

因此,您可以在每四个字符的多个位置拆分base64数据,并且可以将这些块转换回原始位。

我不知道如何在AS / 400上处理字符文件和字节文件,但如果它同时具有这两个概念,那么这应该非常简单。

  • 是每行长度限制的文本文件吗?
  • 是面向行的文本文件,还是只是字符流?
  • 一个字节有多少位?
  • 是在末尾填充的字节文件,因此只能创建跨越整个磁盘扇区的文件吗?

如果你能回答所有这些问题,你还有什么困难?

答案 2 :(得分:2)

将任何给定的字节流拆分成块是一项微不足道的工作。

你可以毫无问题地为任何字节块提供base64。

您面临的问题是,除非您对块(3个字节的倍数)提出特定要求,否则base64编码块的序列将与您想要的实际输出不同。

在C#中,这是一种(草率的)懒散的方式。执行实际上是延迟到调用string.Concat,因此您可以使用chunked字符串执行任何操作。 (如果将其插入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(); //output
    final.Dump(); //output
}
public static class Extensions
{
    public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> list, int chunkSize)
    {
        while(list.Take(1).Count() > 0)
        {
            yield return list.Take(chunkSize);
            list = list.Skip(chunkSize);
        }
    }
}

输出

bG9ydW0gaXBzdW0gZXRjIGxvbCB0aGlzIGlzIGFuIGV4YW1wbGUhIQ==
bG9ydW0gaXBzdW0gZXRjIGxvbCB0aGlzIGlzIGFuIGV4YW1wbGUhIQ==