Translating A Number to An Arbitrary Base
For the sake of ease of copying, sites like Reddit and Imagur have been shortening ids using base 62 encoding. Bitcoin addresses use base 58 (would be base 62 except 0, O, 1, and l are removed). Now you can turn a number into whartever base you like using whatever characters to represent them!
WARNING: If you want your encoded identifiers to be resistant to scraping, use a value from a Cryptographically Secure Pseudo-Random Number Generator as an input to this function. This function by itself is security by obscurity at best.
A bit of explanation (and disclaimers) for the code below:
- This is the best precision and range possible without special libraries. If you go out and use a package for arbitrarily log numbers, the sky's the limit.
- Due to reliance on doubles for performing the logarithm (blame .NET for not having math libraries available for decimal), precision is not guaranteed for an input greater than 2^51. Beyond that, the larger number of characters you have for a base, the less likely you are for the result to be affected.
- This function ceases to work with numbers equal to or greater than 2^96 due to the decimal data type.
using System;
public class Program
{
public static void Main()
{
string characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
decimal input = 63m;
Console.WriteLine(BaseEncode(input, characters));
}
public static string BaseEncode(decimal number, string characters)
{
decimal highestPower = 0;
decimal index = 0;
decimal remainder = 0;
try
{
decimal numCharacters = characters.Length;
// Invalid value check
if(number != Decimal.Floor(number) || number < 0)
{
return "";
}
if(number < numCharacters)
{
return characters[(int)number] + "";
}
highestPower = (decimal)Math.Pow((double)numCharacters, Math.Floor(Math.Log((double)number, (double)numCharacters)));
index = (decimal)Math.Floor(number / highestPower);
remainder = number - (index * highestPower);
return characters[(int)index] + BaseEncode(remainder, characters);
}
catch
{
Console.WriteLine("Index: " + index);
Console.WriteLine("HighestPower: " + highestPower);
return "";
}
}
}