Skip to content

Instantly share code, notes, and snippets.

@yutopio
Last active January 4, 2016 08:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yutopio/8593518 to your computer and use it in GitHub Desktop.
Save yutopio/8593518 to your computer and use it in GitHub Desktop.
Encoder/decoder for byte array into string with 0-9,a-v
using System;
using System.Diagnostics;
using System.Text;
class Program
{
static void Main(string[] args)
{
var rnd = new Random(1);
for (var i = 0; i < 5000; i++)
{
int len = rnd.Next(1000);
var buf1 = new byte[len];
rnd.NextBytes(buf1);
var str = Encode(buf1);
var buf2 = Decode(str);
if (buf1.Length != buf2.Length)
{
Debug.Assert(buf1.Length % 5 != 0);
Debug.Assert(buf1.Length == buf2.Length - 1);
Debug.Assert(buf2[buf2.Length - 1] == 0);
for (var j = 0; j < buf1.Length; j++)
Debug.Assert(buf1[j] == buf2[j]);
}
else Debug.Assert(buf1.Length % 5 == 0);
for (var j = 0; j < buf1.Length; j++)
Debug.Assert(buf1[j] == buf2[j]);
}
}
static string Encode(byte[] bytes)
{
if (bytes == null || bytes.Length == 0)
return string.Empty;
var ret = new StringBuilder((int)Math.Ceiling(bytes.Length * 8 / 5f));
bool cont = true;
for (int i = -1, rest = 0; cont; )
{
int append;
if (rest == 0)
if (bytes.Length == ++i) break;
else append = bytes[i] >> (rest = 3);
else if (rest < 5)
{
rest = 5 - rest;
append = bytes[i] << rest;
if (bytes.Length != ++i)
append |= bytes[i] >> (rest = 8 - rest);
else
cont = false;
}
else
append = bytes[i] >> (rest -= 5);
append &= 31;
ret.Append((char)(append < 10 ? '0' + append : 'a' - 10 + append));
}
return ret.ToString();
}
static byte[] Decode(string value)
{
if (value == null || value.Length == 0)
return new byte[0];
var ret = new byte[(int)Math.Ceiling(value.Length * 5 / 8f)];
var rest = 0;
var i = -1;
foreach (var ch in value)
{
var append = ch <= '9' ? ch - '0' : ch - 'a' + 10;
if (rest == 0)
ret[++i] = (byte)(append << (rest = 3));
else if (rest < 5)
{
ret[i] |= (byte)(append >> (rest = 5 - rest));
ret[++i] = (byte)(append << (rest = 8 - rest));
}
else
ret[i] |= (byte)(append << (rest -= 5));
}
return ret;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment