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

Problems with writing bytes format of string data in Text File in C#

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

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文件中字节按以下方式写入

但是当我在字节数组中分配了一些随机值并使用 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);
    }
}

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

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

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

仅供参考 - 我不想将数据保留为 Base64String 格式,我希望它采用二进制格式。

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

这个代码片段会给你同样的结果。

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

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

如果安全性不是问题,并且您只是不希望在干预设置文件时使用平均使用量来查找您的数据,那么简单的 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 范围内,反之亦然。感谢我描述的 属性,无论 text-reader 试图以 ASCII 或 UTF-8 解析,它只会得到乱码。

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