在C#中的文本文件中写入字符串数据的字节格式的问题

时间:2016-10-03 06:04:03

标签: c# string file binarywriter

我有一个本地存储的文本文件。我想在那里存储二进制格式的字符串数据,然后再次检索数据。在以下代码段中,我完成了转换。

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
class ConsoleApplication
{
    const string fileName = "AppSettings.dat";

    static void Main()
    {
        string someText = "settings";
        byte[] byteArray = Encoding.UTF8.GetBytes(someText);
        int byteArrayLenght = byteArray.Length;
        using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create)))
        {
            writer.Write(someText);
        }
        byte[] x = new byte[byteArrayLenght];

        if (File.Exists(fileName))
        {
            using (BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open)))
            {
                x = reader.ReadBytes(byteArrayLenght);
            }
            string str = Encoding.UTF8.GetString(x);
            Console.Write(str);
            Console.ReadKey();
        }
    }
}

在AppSettings.dat文件中,字节按以下方式写入 enter image description here

但是当我在字节数组中分配了一些随机值并使用BinaryWriter将其保存在文件中时,就像我在下面的代码片段中所做的那样

const string fileName = "AppSettings.dat";

static void Main()
{
    byte[] array = new byte[8];
    Random random = new Random();
    random.NextBytes(array);

    using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create)))
    {
        writer.Write(array);
    }
}

它实际上以二进制格式将数据保存在文本文件中,如图所示。 enter image description here

我不明白为什么(在我的第一种情况下)从显示人类可读格式的字符串转换的字节数据,我希望以不可读的字节格式保存数据(后一种情况)。对此有何解释?

有什么方法可以在不接近蛮力的情况下以二进制格式存储字符串数据?

仅供参考 - 我不想保留Base64String格式的数据,我希望它是二进制格式。

2 个答案:

答案 0 :(得分:1)

如果安全性不是问题,而您只是不希望平均使用率在插入设置文件时找到您的数据,那么简单的XOR就可以:

const string fileName = "AppSettings.dat";

static void Main()
{
    string someText = "settings";
    byte[] byteArray = Encoding.UTF8.GetBytes(someText);

    for (int i = 0; i < byteArray.Length; i++)
    {
        byteArray[i] ^= 255;
    }

    File.WriteAllBytes(fileName, byteArray);

    if (File.Exists(fileName))
    {
        var x = File.ReadAllBytes(fileName);

        for (int i = 0; i < byteArray.Length; i++)
        {
            x[i] ^= 255;
        }

        string str = Encoding.UTF8.GetString(x);
        Console.Write(str);
        Console.ReadKey();
    }
}

它利用了字符编码的一个有趣属性:

  • 在ASCII中,0-127范围包含最常用的字符(a到z,0到9),128-256范围只包含特殊符号和重音
  • 出于兼容性原因,在UTF-8中,0-127范围包含与ASCII相同的字符,128-256范围具有特殊含义(它告诉解码器将字符编码为多个字节)

我所做的只是翻转每个字节的强位。因此,0-127范围内的所有内容最终都在128-256范围内,反之亦然。感谢我所描述的属性,无论文本阅读器是尝试用ASCII还是UTF-8进行解析,它都只能得到胡言乱语。

请注意,虽然它不会产生人类可读的内容,但它根本不安全。不要用它来存储敏感数据。

答案 1 :(得分:0)

记事本只会读取您的二进制数据并将其转换为UTF8文本。

此代码段会为您提供相同的结果。

byte[] randomBytes = new byte[20];
Random rand = new Random();
rand.NextBytes(randomBytes);
Console.WriteLine(Encoding.UTF8.GetString(randomBytes));

如果您想阻止人们将您的数据转换回字符串。那么你需要加密你的数据。 Here是一个可以帮助您的项目。 但他们仍然能够在文本编辑器中读取数据,因为它将加密数据转换为UFT8。他们无法将其转换回可用数据,除非他们必须密钥解密您的数据。