tags:

views:

1169

answers:

5

Hi,

How would you convert a parapraph to hex notation, and then back again into its original string form?

(C#)

A side note: would putting the string into hex format shrink it the most w/o getting into hardcore shrinking algo's?

A: 
public string ConvertToHex(string asciiString)
{
    string hex = "";
    foreach (char c in asciiString)
    {
        int tmp = c;
        hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
    }
    return hex;
}
Corey Goldberg
use stringbuilder!
Anonymous Box
yeah i should have.. though thats the first piece of C# i've written in a while. Im a Python hacker :)
Corey Goldberg
+2  A: 

What exactly do you mean by "hex notation"? That usually refers to encoding binary data, not text. You'd need to encode the text somehow (e.g. using UTF-8) and then encode the binary data as text by converting each byte to a pair of characters.

using System;
using System.Text;

public class Hex
{
    static void Main()
    {
        string original = "The quick brown fox jumps over the lazy dog.";

        byte[] binary = Encoding.UTF8.GetBytes(original);
        string hex = BytesToHex(binary);
        Console.WriteLine("Hex: {0}", hex);
        byte[] backToBinary = HexToBytes(hex);

        string restored = Encoding.UTF8.GetString(backToBinary);
        Console.WriteLine("Restored: {0}", restored);
    }

    private static readonly char[] HexChars = "0123456789ABCDEF".ToCharArray();

    public static string BytesToHex(byte[] data)
    {
        StringBuilder builder = new StringBuilder(data.Length*2);
        foreach(byte b in data)
        {
            builder.Append(HexChars[b >> 4]);
            builder.Append(HexChars[b & 0xf]);
        }
        return builder.ToString();
    }

    public static byte[] HexToBytes(string text)
    {
        if ((text.Length & 1) != 0)
        {
            throw new ArgumentException("Invalid hex: odd length");
        }
        byte[] ret = new byte[text.Length/2];
        for (int i=0; i < text.Length; i += 2)
        {
            ret[i/2] = (byte)(ParseNybble(text[i]) << 4 | ParseNybble(text[i+1]));
        }
        return ret;
    }

    private static int ParseNybble(char c)
    {
        if (c >= '0' && c <= '9')
        {
            return c-'0';
        }
        if (c >= 'A' && c <= 'F')
        {
            return c-'A'+10;
        }
        if (c >= 'a' && c <= 'f')
        {
            return c-'A'+10;
        }
        throw new ArgumentOutOfRangeException("Invalid hex digit: " + c);
    }
}

No, doing this would not shrink it at all. Quite the reverse - you'd end up with a lot more text! However, you could compress the binary form. In terms of representing arbitrary binary data as text, Base64 is more efficient than plain hex. Use Convert.ToBase64String and Convert.FromBase64String for the conversions.

Jon Skeet
amazing! What does b >> 4 do? shifting?
Anonymous Box
Yes, it shifts the byte right, so you end up with a single nybble (0-15).
Jon Skeet
visually speaking, how does that look? isn't the value of the byte changing now?
Anonymous Box
The byte itself isn't changing - numbers don't actually change their values. It's computing the value of the byte shifted right. To put it another way, just think of that expression as "b/16".
Jon Skeet
Thanks Jon, this has helped me a lot too. I've got to process some text that has been stored in a varchar field as Hex for some reason. The weird things we encounter in day to day development, lol :-)
DoctaJonez
A: 

While I can't help much on the C# implementation, I would highly recommend LZW as a simple-to-implement data compression algorithm for you to use.

coppro
A: 

Perhaps the answer can be more quickly reached if we ask: what are you really trying to do? Converting an ordinary string to a string of a hex representation seems like the wrong approach to anything, unless you are making a hexidecimal/encoding tutorial for the web.

Patrick Szalapski
A: 
static byte[] HexToBinary(string s) {
  byte[] b = new byte[s.Length / 2];
  for (int i = 0; i < b.Length; i++)
    b[i] = Convert.ToByte(s.Substring(i * 2, 2), 16);
  return b;
}
static string BinaryToHex(byte[] b) {
  StringBuilder sb = new StringBuilder(b.Length * 2);
  for (int i = 0; i < b.Length; i++)
    sb.Append(Convert.ToString(256 + b[i], 16).Substring(1, 2));
  return sb.ToString();
}
Hafthor