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

我正在尝试base64编码一个巨大的输入文件,最后得到一个文本输出文件,我试图找出是否有可能逐位编码输入文件,或者我是否需要编码整个什么事情。

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

12

3 答案

逐位 是不可能的,但一次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)的单一尺寸可以使事情更加统一和易于管理。

26
额外
看,我花了一段时间不得不钻研,因为要求是使用特定的缓冲区大小(不是3的倍数)。一旦我的脑屁消失,我只是改变了缓冲区的大小。真的,我是个白痴。虽然每个人都用明显的“使缓冲区大小为3的倍数”回答了这个问题,但是你得到了复选标记,“因为你是第一个。谢谢!
额外 作者 roryhewitt,

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

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

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

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

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

2
额外
没有 - 我是个白痴:(
额外 作者 roryhewitt,

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

您可以毫无问题地将64个字节块替换为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(); //产量
    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==
2
额外