using System; using System.Collections.Generic; using System.Text; namespace Infrastructure.Extensions { public static class Base62Extensions { private const string characterSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; public static string Base62Encode(this string value) { var arr = Encoding.UTF8.GetBytes(value); return Base62Encode(arr); } public static string Base62Decode(this string value) { if (value is null) { throw new ArgumentNullException(nameof(value)); } var arr = new byte[value.Length]; for (var i = 0; i < arr.Length; i++) { arr[i] = (byte)characterSet.IndexOf(value[i], StringComparison.CurrentCulture); } return Base62Decode(arr); } public static string Base62Encode(this byte[] value) { if (value is null) { throw new ArgumentNullException(nameof(value)); } var converted = BaseConvert(value, 256, 62); var builder = new StringBuilder(); for (var i = 0; i < converted.Length; i++) { builder.Append(characterSet[converted[i]]); } return builder.ToString(); } public static string Base62Decode(this byte[] value) { if (value is null) { throw new ArgumentNullException(nameof(value)); } var converted = BaseConvert(value, 62, 256); return Encoding.UTF8.GetString(converted, 0, converted.Length); } private static byte[] BaseConvert(byte[] source, int sourceBase, int targetBase) { var result = new List(); int count; while ((count = source.Length) > 0) { var quotient = new List(); int remainder = 0; for (var i = 0; i != count; i++) { int accumulator = source[i] + remainder * sourceBase; byte digit = System.Convert.ToByte((accumulator - (accumulator % targetBase)) / targetBase); remainder = accumulator % targetBase; if (quotient.Count > 0 || digit != 0) { quotient.Add(digit); } } result.Insert(0, remainder); source = quotient.ToArray(); } var output = new byte[result.Count]; for (int i = 0; i < result.Count; i++) output[i] = (byte)result[i]; return output; } } }