1

I have a text file stored locally. I want to store string data in binary format there and then retrieve the data again. In the following code snippet, I have done the conversion.

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();
        }
    }
}

In the AppSettings.dat file the bytes are written in the following way enter image description here

But when I have assigned some random value in a byte array and save it in a file using BinaryWriter as I have done in the following code snippet

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);
    }
}

It's actually saved the data in binary format in the text file, shown in the picture. enter image description here

I don't understand why (in my first case) the byte data converted from string showing human readable format where I want to save the data in non-readable byte format(later case). What's the explanation regarding this?

Is there any way where I can store string data in binary format without approaching brute force?

FYI - I don't want to keep the data in Base64String format, I want it to be in binary format.

4
  • Your first file is binary, in a way. It just so happens that bytes represent human-readable text. The f and F in your second example are human-readable as well, yet you somehow call the second file "binary". Commented Oct 3, 2016 at 6:07
  • 1
    Depending on the encoding, your byte values may be human readable or maybe not - Take a look at for example the UTF-8 character list. You'll notice that there are many characters which can't be printed in a human readable way. Commented Oct 3, 2016 at 6:09
  • Is there any way so that I can store them in human unreadable way or only in byte value or only 0's and 1's in the file. Anyone will do. Commented Oct 3, 2016 at 6:33
  • 1
    Well, base64 does that, so I'm not sure why you don't want to use it. Anyway, just XOR your data before writing it, and XOR it back against the same value when you read it Commented Oct 3, 2016 at 6:39

2 Answers 2

2

If security isn't a concern, and you just don't want the average usage to find your data while meddling into the settings files, a simple XOR will do:

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();
    }
}

It takes advantage of an interesting property of character encoding:

  • In ASCII, the 0-127 range contains the most used characters (a to z, 0 to 9) and the 128-256 range contains only special symbols and accents
  • For compatibility reasons, in UTF-8 the 0-127 range contains the same characters as ASCII, and the 128-256 range have a special meaning (it tells the decoder that the characters are encoded into multiple bytes)

All I do is flipping the strong-bit of each byte. Therefore, everything in the 0-127 range ends up in the 128-256 range, and vice-versa. Thanks to the property I described, no matter if the text-reader tries to parse in ASCII or in UTF-8, it will only get gibberish.

Please note that, while it doesn't produce human-readable content, it isn't secure at all. Don't use it to store sensitive data.

Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I was looking for. Thanks. I am not storing sensitive data in the text file, just don't want to be it as human readable.
0

The notepad just reads your binary data and converts it to UTF8 text.

This code snippet would give you the same result.

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

If you want to stop people from converting your data back to a string. then you need to encrypt your data. Here is a project that can help you with that. But they are still able to read the data in a text editor because it converts your encrypted data to UFT8. They can't Convert it back to usable data unless they have to key to decrypt your data.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.