简体   繁体   English

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

[英]C# split byte array from file

Hello I'm doing an encryption algorithm which reads bytes from file (any type) and outputs them into a file. 您好我正在做一个加密算法,它从文件(任何类型)读取字节并将它们输出到文件中。 The problem is my encryption program takes only blocks of 16 bytes so if the file is bigger it has to be split into blocks of 16, or if there's a way to read 16 bytes from the file each time it's fine. 问题是我的加密程序只占用16个字节的块,因此如果文件较大,则必须将其拆分为16个块,或者如果有一种方法可以在每次读取文件时从文件中读取16个字节。

The algorithm is working fine with hard coded input of 16 bytes. 该算法适用于16字节的硬编码输入。 The ciphered result has to be saved in a list or array because it has to be deciphered the same way later. 加密的结果必须保存在列表或数组中,因为它必须以后以相同的方式解密。 I can't post all my program but here's what I do in main so far and cannot get results 我不能发布我的所有程序,但这是我到目前为止主要做的事情,无法得到结果

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);
    }
}

I know that my loops always add the first 16 bytes from the byte array but I tried many ways and nothing work. 我知道我的循环总是从字节数组中添加前16个字节,但我尝试了很多方法,没有任何效果。 It won't let me index the bytes array or copy an item to a temp variable like temp = bytes[i] . 它不会让我索引字节数组或将项复制到临时变量,如temp = bytes[i] The ToBytes method is irrelevant, it just prints the elements as bytes. ToBytes方法无关紧要,它只是将元素打印为字节。

No need to read the whole mess into memory if you can only process it a bit at a time... 如果你一次只能处理一下,就不需要将整个内容读入内存......

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));
    }
}

I would like to recommend you to change the interface for your Cipher() method: instead of passing the entire array , it would be better to pass the source and destination arrays and offset - block by block encryption . 我建议您更改Cipher()方法的接口:不是传递整个数组 ,最好是传递源和目标数组以及偏移 - 逐块加密

Pseudo-code is below. 伪代码如下。

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)!
}

Usage: 用法:

  1. For small files (one memory allocation for destination buffer, block by block encryption): 对于小文件 (目标缓冲区的一个内存分配,逐块加密):

     // 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); } 

    So, the main advantage of this approach - it elimitates additional memory allocations : the destination array is allocated at once. 因此,这种方法的主要优点 - 它消除了额外的内存分配 :目标数组一次分配。 There is also no copy-memory operations. 没有复制内存操作。

  2. For files of any size (streams, block by block encryption): 对于任何大小的文件(流,逐块加密):

      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); } } 

You can use Array.Copy 您可以使用Array.Copy

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM