|
|||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
IntroductionI often have to encode positive integer ids into text to send over a socket and like to keep the messages as short as possible and the encoding / decoding as fast as possible. Using c# it's easy to send your integer id as base 10 or base 16 strings but using base 64 or base 62 or base 36 or base 32 encoded strings saves a lot of space. There is another article on this site encoding and decoding base 36 integers but it uses Math.Pow which is very slow. By choosing Base 64 (made from 0-9, A-Z, a-z, +, -) which fits perfectly into 6 bits I can encode and decode very quickly. I can also fit a nine or ten digit base 10 Int32 into a five character base 64 string. In fact this app shows that C#'s Convert.ToInt32 followed by Convert.ToString is 5½ times slower than using my base 64 encoding functions! The code is very simple and easily modified to Int64 or passing a char[] with offset which is useful for socket stuff. For the encode you choose the number of characters to enode into. One character gives you 0-63 of course, two is 4096, three 262,144 etc. It would be easy to translate to C or C++ as well. If you download the app you can see some demonstrations and a speed test using the high performance timer. But otherwise all the code you need is here: using System; using System.Collections.Generic; using System.Text; class Base64 { static char[] b64e = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '+', '/'}; static int[] b64d = new int[] { 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,062,000,000,000,063,000,001, 002,003,004,005,006,007,008,009,000,000, 000,000,000,000,000,010,011,012,013,014, 015,016,017,018,019,020,021,022,023,024, 025,026,027,028,029,030,031,032,033,034, 035,000,000,000,000,000,000,036,037,038, 039,040,041,042,043,044,045,046,047,048, 049,050,051,052,053,054,055,056,057,058, 059,060,061,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000,000,000, 000,000,000,000,000,000}; public static string b64ConvertInt(int value, int length) { // length should be between 1 and 5 only if (length == 5) { char[] c = new char[5]; c[0] = b64e[(value & 1056964608) >> 24]; c[1] = b64e[(value & 16515072) >> 18]; c[2] = b64e[(value & 258048) >> 12]; c[3] = b64e[(value & 4032) >> 06]; c[4] = b64e[(value & 63)]; return new string(c); } else if (length == 4) { char[] c = new char[4]; c[0] = b64e[(value & 16515072) >> 18]; c[1] = b64e[(value & 258048) >> 12]; c[2] = b64e[(value & 4032) >> 06]; c[3] = b64e[(value & 63)]; return new string(c); } else if (length == 3) { char[] c = new char[3]; c[0] = b64e[(value & 258048) >> 12]; c[1] = b64e[(value & 4032) >> 06]; c[2] = b64e[(value & 63)]; return new string(c); } else if (length == 2) { char[] c = new char[2]; c[0] = b64e[(value & 4032) >> 06]; c[1] = b64e[(value & 63)]; return new string(c); } else { return Convert.ToString(b64e[(value & 63)]); } } public static int b64ConvertString(string s) { // string s should be between 1 and 5 character long only int n = s.Length; char[] c = s.ToCharArray(); if (n == 5) { return (b64d[c[0]] << 24) + (b64d[c[1]] << 18) + (b64d[c[2]] << 12) + (b64d[c[3]] << 6) + b64d[c[4]]; } else if (n == 4) { return (b64d[c[0]] << 18) + (b64d[c[1]] << 12) + (b64d[c[2]] << 6) + b64d[c[3]]; } else if (n == 3) { return (b64d[c[0]] << 12) + (b64d[c[1]] << 6) + b64d[c[2]]; } else if (n == 2) { return (b64d[c[0]] << 6) + b64d[c[1]]; } else if (n == 1) { return b64d[c[0]]; } return 0; } }
|
||||||||||||||||||||||||||||||||