Last active
January 4, 2016 08:09
-
-
Save yutopio/8593518 to your computer and use it in GitHub Desktop.
Encoder/decoder for byte array into string with 0-9,a-v
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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