Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Convert an integer to a base 64 string and back again very quickly

0.00/5 (No votes)
4 Jul 2008 1  
Convert a positive 32 bit integer to a base 64 string. This is the fastest and shortest encoding / decoding of an integer to / from text. Easily modified for 64 bit integers.

Introduction

I 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 encode 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;
    }
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here