0

您好我正在做一个加密算法,它从文件(任何类型)中读取字节并将它们输出到文件中。问题是我的加密程序只需要 16 个字节的块,所以如果文件更大,它必须分成 16 个块,或者如果有办法每次从文件中读取 16 个字节就可以了。

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

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 个字节,但我尝试了很多方法,但没有任何效果。它不会让我索引字节数组或将项目复制到临时变量,如temp = bytes[i]. ToBytes 方法无关紧要,它只是将元素打印为字节。

4

3 回答 3

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));
    }
}
于 2013-01-25T19:10:15.517 回答
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);
            }
        }
    
于 2013-01-25T19:11:05.527 回答
0

您可以使用Array.Copy

byte[] temp = new byte[16];
Array.Copy(bytes, i, temp, 0, 16);
于 2013-01-25T19:04:56.223 回答