Last active
June 18, 2021 14:02
-
-
Save firepacket/8e9077792ea63a069ca6b0acf3dd4d21 to your computer and use it in GitHub Desktop.
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.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
/** | |
* ShortURL: Bijective conversion between natural numbers (IDs) and short strings | |
* | |
* ShortURL.Encode() takes an ID and turns it into a short string | |
* ShortURL.Decode() takes a short string and turns it into an ID | |
* | |
* Features: | |
* + VERY large alphabet all composite numbers from 33-64 are included to find the shortest and nicest looking URL. | |
* + Offensive words have been made very unlikely due to design. | |
* + This allows for much more room (support for ULONG data type) at the expense of sometimes adding 1 letter for shorter numbers. | |
* + This method guarantees the shortest URL at the expense of one digit, but this is often reversed and some long numbers can become extra short! | |
* + Ultimate PRIVACY. Search space is enormous. Nobody will ever find anyone else's URL. | |
* + Added extra char "." that is acceptable in URLs | |
* + No extra DB lookups | |
* | |
* Example output: | |
* 434433 <=> zfMn- | |
* 1234 <=> w-x | |
* 8989800 <=> gVXG. | |
* 132 <=> pc_ | |
* 2 <=> _c | |
* (ulong) 18446744073709551615 <=> dD5E.dbtn3-s | |
* (long) 9223372036854775807 <=> iD-kBTykgmf8 | |
* (uint) 4294967295 <=> efGCg_s | |
* (int) 2147483647 <=> nfhj.gy | |
* (ushort) 65535 <=> t_zs | |
* (byte) 255 <=> ie- | |
*/ | |
public class ShortURL | |
{ | |
private static string Keys = "abcdeghijkmnpqrstuvwxyz23456789_"; // Do not change this string length. If you want to remove something, replace it with something else. | |
private static string AllChars = "abcdefghjkmnpqrstvwxyzABCDE-_.FGHJKLMNPQRSTVWXYZ1234567890oOiIuU"; // Do not change this string length. If you want to remove something, replace it with something else. | |
private static Dictionary<char, string> DAlphabet = new Dictionary<char, string>(); | |
static ShortURL() // Contains all composite numbers from 33-64 | |
{ | |
for (int i = 0; i < Keys.Length; i++) | |
DAlphabet[ Keys[ i ] ] = new string(AllChars.Take(AllChars.Length - i).ToArray()); | |
} | |
public static string Encode(ulong num) | |
{ | |
ulong n = num; | |
List<string> s = new List<string>(); | |
foreach (char t in Keys) | |
{ | |
string A = DAlphabet[ t ]; | |
ulong B = (ulong)A.Length; | |
var S = new StringBuilder(); | |
while (n > 0) // Because we use all composite numbers, we will find the shortest url possible here! | |
{ | |
S.Insert(0, A.ElementAt((int)(n % B))); | |
n = n / B; | |
} | |
n = num; | |
S.Insert(0, t); | |
s.Add(S.ToString()); | |
} | |
// Prioritizes certain characters. Changing this will make your version unique. | |
var sort = s.OrderBy(x => x.Length).ThenByDescending(x => x.Contains("_") || x.Contains("-") || x.Contains(".")).ThenByDescending(x => x.ToCharArray().Count(z => char.IsLower(z))); | |
return sort.ToArray()[ 0 ]; | |
} | |
public static ulong Decode(string str) | |
{ | |
char c = str[ 0 ]; | |
string Alphabet = DAlphabet[ c ]; | |
ulong Base = (ulong)Alphabet.Length; | |
str = str.Substring(1, str.Length - 1); | |
ulong num = 0; | |
for (var i = 0; i < str.Length; i++) | |
{ | |
num = num * Base + (ulong)Alphabet.IndexOf(str.ElementAt(i)); | |
} | |
return num; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment