我需要将编码的文本保存到二进制文件中。用BinaryWriter".bin",用BinaryReader读取。
我使用霍夫曼编码对文本和字符进行编码,然后我使字符串生成器更易于阅读,最后我得到了:
A:1111;l:1011;a:00; :01;m:1010;k:100;o:1110;t:1100;e:11010;.:11011;
111110110001101000011001110110000010001100111011000110100001111110111101011011
当我以这种方式将其保存到二进制文件时:
(BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)))
foreach (var bit in binaryString)
writer.Write(bit);
通过记事本打开.bin文件,它会显示全文。编码。我需要让它不可读。例如,如果您通过记事本在旧系统中打开.exe,它会显示随机字符,例如 [、[] ##$# $# #%$^$ ^&% 或类似的东西。
我该怎么做?
我还需要读取该二进制文件并对其进行解码。读数:
var bits = new List<byte>();
int position = 0,
length;
using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open)))
{
length = (int)reader.BaseStream.Length;
while (position < length)
{
bits.Add(reader.ReadByte());
position++;
}
}
和解码:
Console.WriteLine("nDekodujemy!n");
int lineFeed = 0x0a,
semicolon = 0x3b,
colon = 0x3a;
List<byte> structBits = new List<byte>();
List <byte> textBits = new List<byte>();
bool isStructBits = true;
foreach(var bit in bits)
{
if (bit == lineFeed)
{
isStructBits = false;
continue;
}
if (isStructBits)
structBits.Add(bit);
else
textBits.Add(bit);
}
Console.Write("Zdekodowana struktura: ");
foreach (var bit in structBits)
Console.Write((char)bit);
Console.Write("nZakodowany tekst: ");
foreach (var bit in textBits)
Console.Write((char)bit);
var charactersMap = new Dictionary<char, string>();
Console.WriteLine("nDekodowanie struktury!");
{
bool isKey = true, isValue = false;
char key = ' ';
string value = "";
foreach (var bit in structBits)
{
Console.WriteLine("Key: {0}", key);
if (isKey)
{
if (!charactersMap.ContainsKey((char)bit))
{
key = (char)bit;
isKey = false;
}
}
if (bit == colon)
{
isValue = true;
continue;
}
if (bit == semicolon)
{
isValue = false;
isKey = true;
charactersMap.Add(key, value);
value = "";
}
if (isValue)
{
value += (char)bit;
}
}
}
Console.WriteLine("nKluczy: {0}nZdekodowane klucze:", charactersMap.Count);
foreach (var key in charactersMap.Keys)
Console.WriteLine("{0} = {1}", key, charactersMap[key]);
Console.WriteLine("nDekodowanie tekstu!");
string decodedText = "";
string temp = "";
foreach (var bit in textBits)
{
Console.WriteLine("Bit: {0}", (char)bit);
Console.WriteLine("Temp: {0}", temp);
temp += (char)bit;
foreach (var key in charactersMap.Keys)
if (charactersMap[key] == temp)
{
decodedText += key;
temp = "";
break;
}
}
Console.WriteLine("nnZdekodowano: {0}", decodedText);
有人可以帮忙吗?
如果我清楚地理解您要做什么,那么您正在将编码消息的每个位写入整个字节,但您想将它们写入位。因此,在将它们写入文件之前,您应该将此位打包成字节。在构建二进制字符串的位置,您应该将每个 8 位合并到一个字节中(使用位操作)。
假设binaryString
属于string
类型,您可以使用如下所示的方法将其转换为byte
的集合:
public static IEnumerable<byte> AsHuffmanCode(this string source)
{
const int BitsPerByte = 8;
const int LastBit = 7;
byte huffmanByte = 0;
for (var index = 0; index < source.Length; index++)
{
var bit = source[index] == '0' ? 0 : 1;
var bitPosition = index % BitsPerByte;
huffmanByte |= (byte)(bit << bitPosition);
if (bitPosition == LastBit)
{
yield return huffmanByte;
huffmanByte = 0;
}
}
}
像这样使用它:
using (var writer = new BinaryWriter(File.Open(path, FileMode.Create)))
{
foreach (var huffmanByte in binaryString.AsHuffmanCode())
writer.Write(huffmanByte);
}
有关正在运行的版本,请参阅此 .NET 小提琴。
基本思想是读取char
char
的字符串,累积字符的位值,并在每 8 个字符后返回该累积值。累加是通过对位值进行 OR 运算来实现的,每个位值根据其在字符串中的位置进行移位。
将byte
解码为string
应该是直截了当的。只需执行反向操作即可。
请注意,此方法不执行任何错误检查。