您好我正在做一个加密算法,它从文件(任何类型)读取字节并将它们输出到文件中。问题是我的加密程序只占用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方法无关紧要,它只是将元素打印为字节。
答案 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)!
}
用法:
对于小文件(目标缓冲区的一个内存分配,逐块加密):
// 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);
}
因此,这种方法的主要优点 - 它可以消除额外的内存分配:目标数组一次分配。还有无复制内存操作。
对于任何大小的文件(流,逐块加密):
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);