Здравствуйте. Пишу программу по стеганографии wav файлов. Помимо секретного сообщения в аудио необходимо встроить ключ, который считывается из файла. Помогите переделать код таким образом, чтобы ключ вставлялся сразу после служебных символов. После вставки ключа вставлялось бы сообщение и далее оставшаяся не измененная часть аудио файла. Или же при извлечении сообщения не будет возможности различить где ключ, а где само сообщение?
Код встраивания сообщения:
public void Hide(Stream messageStream, Stream keyStream)
{
byte[] waveBuffer = new byte[_bytesPerSample];
byte message, bit, waveByte;
int messageBuffer; //receives the next byte of the message or -1
int keyByte; //distance of the next carrier sample
while ((messageBuffer = messageStream.ReadByte()) >= 0)
{
//read one byte of the message stream
message = (byte)messageBuffer;
//for each bit in message
for (int bitIndex = 0; bitIndex < 8; bitIndex++)
{
//read a byte from the key
keyByte = GetKeyValue(keyStream);
//skip a couple of samples
for (int n = 0; n < keyByte - 1; n++)
{
//copy one sample from the clean stream to the carrier stream
_sourceStream.Copy(waveBuffer, 0, waveBuffer.Length, _destinationStream);
}
//read one sample from the wave stream
_sourceStream.Read(waveBuffer, 0, waveBuffer.Length);
waveByte = waveBuffer[_bytesPerSample - 1];
//get the next bit from the current message byte...
if ((message & (byte) (1 << bitIndex)) > 0)
bit = 1;
else
bit = 0;
//...place it in the last bit of the sample
if ((bit == 1) && ((waveByte % 2) == 0))
{
waveByte += 1;
}
else if ((bit == 0) && ((waveByte % 2) == 1))
{
waveByte -= 1;
}
waveBuffer[_bytesPerSample - 1] = waveByte;
//write the result to destinationStream
_destinationStream.Write(waveBuffer, 0, _bytesPerSample);
}
}
//copy the rest of the wave without changes
waveBuffer = new byte[_sourceStream.Length - _sourceStream.Position];
_sourceStream.Read(waveBuffer, 0, waveBuffer.Length);
_destinationStream.Write(waveBuffer, 0, waveBuffer.Length);
}
Операции с ключом:
public static long CheckKeyForMessage(Stream keyStream, long messageLength)
{
long messageLengthBits = messageLength * 8;
long countRequiredSamples;
if (messageLengthBits > keyStream.Length && keyStream.Length != 0)
{
long keyLength = keyStream.Length;
// read existing key
byte[] keyBytes = new byte[keyLength];
keyStream.Read(keyBytes, 0, keyBytes.Length);
// Every byte stands for the distance between two useable samples.
// The sum of those distances is the required count of samples.
countRequiredSamples = SumKeyArray(keyBytes);
// The key must be repeated, until every bit of the message has a key byte.
double countKeyCopies;
countKeyCopies = messageLengthBits / keyLength;
countRequiredSamples = (long)(countRequiredSamples * countKeyCopies);
}
else
{
byte[] keyBytes = new byte[messageLengthBits];
keyStream.Read(keyBytes, 0, keyBytes.Length);
countRequiredSamples = SumKeyArray(keyBytes);
}
keyStream.Seek(0, SeekOrigin.Begin);
return countRequiredSamples;
}
private static long SumKeyArray(byte[] values)
{
long sum = 0;
foreach (int value in values)
{
// '0' causes a distance of one sample,
// every other key causes a distance of its exact value.
if (value == 0)
sum += 1;
else
sum += value;
}
return sum;
}
/// <summary>
/// Read the next byte of the key stream.
/// Reset the stream if it is too short.
/// </summary>
/// <param name="keyStream">The key stream</param>
/// <returns>The next key byte</returns>
private static byte GetKeyValue(Stream keyStream)
{
int keyValue;
if ((keyValue = keyStream.ReadByte()) < 0)
{
keyStream.Seek(0, SeekOrigin.Begin);
keyValue = keyStream.ReadByte();
if (keyValue == 0) { keyValue = 1; }
}
return (byte)keyValue;
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Есть VSTO Add-in проект для PowerPoint, который в одной из своих частей делает отрисовку маркированного списка
Хочу сделать на aspnet core с авторизацией, однако на сайте планируется авторизация только через соц