C#从文件中拆分字节数组

时间:2013-01-25 18:57:17

标签: c# arrays file split byte

您好我正在做一个加密算法,它从文件(任何类型)读取字节并将它们输出到文件中。问题是我的加密程序只占用16个字节的块,因此如果文件较大,则必须将其拆分为16个块,或者如果有一种方法可以在每次读取时从文件中读取16个字节。

该算法适用于16字节的硬编码输入。加密的结果必须保存在列表或数组中,因为它必须以后以相同的方式解密。我不能发布我的所有程序,但这是我到目前为止主要做的事情,并且无法获得结果

static void Main(String[] args)
{
    byte[] bytes = File.ReadAllBytes("path to file");
    var stream = new StreamReader(new MemoryStream(bytes));
    byte[] cipherText = new byte[16];
    byte[] decipheredText = new byte[16];

    Console.WriteLine("\nThe message is: ");
    Console.WriteLine(stream.ReadToEnd());

    AES a = new AES(keyInput);
    var list1 = new List<byte[]>();
    for (int i = 0; i < bytes.Length; i+=16)
    {
        a.Cipher(bytes, cipherText);
        list1.Add(cipherText);
    }

    Console.WriteLine("\nThe resulting ciphertext is: ");
    foreach (byte[] b in list1)
    {       
        ToBytes(b);
    }
}

我知道我的循环总是从字节数组中添加前16个字节,但我尝试了很多方法而且没有任何效果。它不会让我索引bytes数组或将项复制到像temp = bytes[i]这样的临时变量。 ToBytes方法无关紧要,它只是将元素打印为字节。

3 个答案:

答案 0 :(得分:1)

如果你一次只能处理一下,就不需要将整个内容读入内存......

var filename = @"c:\temp\foo.bin";
using(var fileStream = new FileStream(filename, FileMode.Open))
{
    var buffer = new byte[16];
    var bytesRead = 0;
    while((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        // do whatever you need to with the next 16-byte block
        Console.WriteLine("Read {0} bytes: {1}", 
                bytesRead, 
                string.Join(",", buffer));
    }
}

答案 1 :(得分:1)

我建议您更改Cipher()方法的界面:不要传递整个数组,最好传递源和目标数组和偏移 - 逐块加密

伪码在下面。

void Cipher(byte[] source, int srcOffset, byte[] dest, int destOffset)
{
    // Cipher these bytes from (source + offset) to (source + offset + 16),
    // write the cipher to (dest + offset) to (dest + offset + 16)
    // Also I'd recommend to check that the source and dest Length is less equal to (offset + 16)!
}

用法:

  1. 对于小文件(目标缓冲区的一个内存分配,逐块加密):

    // You can allocate the entire destination buffer before encryption!
    byte[] sourceBuffer = File.ReadAllBytes("path to file");
    byte[] destBuffer = new byte[sourceBuffer.Length];
    
    // Encrypt each block.
    for (int offset = 0; i < sourceBuffer.Length; offset += 16)
    {
        Cipher(sourceBuffer, offset, destBuffer, offset);
    }
    

    因此,这种方法的主要优点 - 它可以消除额外的内存分配:目标数组一次分配。还有无复制内存操作。

  2. 对于任何大小的文件(流,逐块加密):

        byte[] inputBlock = new byte[16];
        byte[] outputBlock = new byte[16];
        using (var inputStream = File.OpenRead("input path"))
        using (var outputStream = File.Create("output path"))
        {
            int bytesRead;
            while ((bytesRead = inputStream.Read(inputBlock, 0, inputBlock.Length)) > 0)
            {
                if (bytesRead < 16)
                {
                    // Throw or use padding technique.
                    throw new InvalidOperationException("Read block size is not equal to 16 bytes");
    
                    // Fill the remaining bytes of input block with some bytes.
                    // This operation for last block is called "padding".
                    // See http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Padding
                }
    
                Cipher(inputBlock, 0, outputBlock, 0);
                outputStream.Write(outputBlock, 0, outputBlock.Length);
            }
        }
    

答案 2 :(得分:0)

您可以使用Array.Copy

byte[] temp = new byte[16];
Array.Copy(bytes, i, temp, 0, 16);