简体   繁体   中英

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.

The algorithm is working fine with hard coded input of 16 bytes. 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. It won't let me index the bytes array or copy an item to a temp variable like temp = bytes[i] . The ToBytes method is irrelevant, it just prints the elements as bytes.

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 .

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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