Einstein argued that there must be simplified explanations of nature, because God is not capricious or arbitrary. No such faith comforts the software engineer. --Fred Brooks, Jr.

# Cambia.BaseN Documentation and Code Samples

This article provides documentation and code samples for the Cambia.BaseN Nuget package for converting and representing base-N numbers.

For more in-depth info, please see this post: Intro to Number Bases and the Cambia.BaseN Package.

## Create an Alphabet

An alphabet is the set of unique digits used to represent a number. The number of unique digits in your alphabet is the base, or radix.

For example, base-10 (decimal) uses an alphabet with ten digits 0123456789. Base-16 (hexadecimal) uses an alphabet with sixteen digits 0123456789ABCDEF.

Built-in:

Go here to learn more about the built-in alphabets. Up to base-62 they are exactly what you'd expect, after that things can get a touch wonky.

However, our Cambia95 standard alphabet reduces the wonk.

```
// You'll need the following using statement
using Cambia.BaseN;

// Use one of the static properties for special alphabets.
// This is likely all you'll every need.

BaseNAlphabet alpha = null;
alpha = BaseNAlphabet.Base2;
alpha = BaseNAlphabet.Base8;
alpha = BaseNAlphabet.Base10;
alpha = BaseNAlphabet.Base16;
alpha = BaseNAlphabet.Base36;
alpha = BaseNAlphabet.Base62;
alpha = BaseNAlphabet.Base64;
alpha = BaseNAlphabet.Base64_RFC4648;
alpha = BaseNAlphabet.Base64_RFC4648_Safe;
alpha = BaseNAlphabet.Base72;
alpha = BaseNAlphabet.Base72_Safe;
alpha = BaseNAlphabet.Base85;
alpha = BaseNAlphabet.Base85_Ascii85;
alpha = BaseNAlphabet.Base94;
alpha = BaseNAlphabet.Base95;

// Or get an alphabet of any length based on a built-in alphabet:

```

Custom:

```
// Create the standard base-10 alphabet
BaseNAlphabet a = new BaseNAlphabet("0123456789");

// Create a bizarre reverse base-10 alphabet
BaseNAlphabet a = new BaseNAlphabet("9876543210");

// Use the unique letters in your name to create a funky personalized alphabet
// In my case, it's a base-4 alphabet
BaseNAlphabet a = new BaseNAlphabet("STEV");

// Reset resets the class as if it were freshly instantiated
a.Reset("MARY");

// You can also instantiate with a character array
a = new BaseNAlphabet(new char[]{'M', 'i', 'c', 'h', 'a', 'e', 'l' });

// Or reset with one
a.Reset(new char[]{'s','a','b','i','n','e'});

```

Properties:

Alphabets are principally used as inputs to other operations, but they have a few readonly properties which are mainly used internally, but which might still be useful for you to know about.

```

int base = BaseNAlphabet.Base10.Radix; // base = 10

// SupportsNegative -
bool canDoNeg = BaseNAlphabet.Base10.SupportsNegative; // canDoNeg=true

// If an alphabet contains the minus sign, then it does not support negative numbers.
canDoNeg = BaseNAlphabet.Base64_RFC4648_Safe.SupportsNegative; // canDoNeg=false
canDoNeg = BaseNAlphabet.Base95.SupportsNegative; // canDoNeg=false

// ContainsWhitespace -
bool ws = BaseNAlphabet.Base10.ContainsWhiteSpace; // ws=false

// Base95 includes the space character as a digit so it does have whitespace
ws = BaseNAlphabet.Base95.ContainsWhiteSpace; // ws=true

```

## The BaseConverter Class - Parsing and Converting

The BaseConverter class is a static object with all static methods to Parse, output and convert numbers in different bases.

Parse:

```

// If you want to use the BigInteger struct
// which allows integers of unlimited size you may
// need to include this namespace
using System.Numerics;

// Parse a binary number
// BaseConverter.Parse(string number, BaseNAlphabet sourceAlphabet);
// If a number can't fit in the specified output type, you'll get an OverflowException

BigInteger bi = BaseConverter.Parse("010100011010", BaseNAlphabet.Base2);
Int64 lg = BaseConverter.ParseToInt64("010100011010", BaseNAlphabet.Base2);
UInt64 ulg = BaseConverter.ParseToUInt64("010100011010", BaseNAlphabet.Base2);
Int32 i = BaseConverter.ParseToInt32("010100011010", BaseNAlphabet.Base2);
UInt32 ui = BaseConverter.ParseToUInt32("010100011010", BaseNAlphabet.Base2);
Guid g = BaseConverter.ParseToGuid("010100011010", BaseNAlphabet.Base2);

// Parse a hex number

bi = BaseConverter.Parse("A73FFB397", BaseNAlphabet.Base16);
lg = BaseConverter.ParseToInt64("A73FFB397", BaseNAlphabet.Base16);
ulg = BaseConverter.ParseToUInt64("A73FFB397", BaseNAlphabet.Base16);
i = BaseConverter.ParseToInt32("A73FFB397", BaseNAlphabet.Base16);
ui = BaseConverter.ParseToUInt32("A73FFB397", BaseNAlphabet.Base16);
g = BaseConverter.ParseToGuid("A73FFB397", BaseNAlphabet.Base16);

```

TryParse:

```
// TryParse a binary number
// bool result = BaseConverter.TryParse(string number, BaseNAlphabet sourceAlphabet, out T num);

bool result = false;

BigInteger bi = new BigInteger();
result = BaseConverter.TryParse("010100011010", BaseNAlphabet.Base2, out bi);

long lg = 0;
result = BaseConverter.TryParse("010100011010", BaseNAlphabet.Base2, out lg);

ulong ulg = 0;
result = BaseConverter.TryParse("010100011010", BaseNAlphabet.Base2, out ulg);

int i = 0;
result = BaseConverter.TryParse("010100011010", BaseNAlphabet.Base2, out i);

uint ui = 0;
result = BaseConverter.TryParse("010100011010", BaseNAlphabet.Base2, out ui);

Guid g = Guid.Empty;
result = BaseConverter.TryParse("010100011010", BaseNAlphabet.Base2, out g);

```

ToBaseN:

```
// Transform a number to base-n
// string output = BaseConverter.ToBaseN(T sourceNumber, BaseNAlphabet outputAlphabet);
// T=BigInteger, Guid, Int64, UInt64, Int32, UInt32

BigInteger bi = new BigInteger(1000);
string output = BaseConverter.ToBaseN(bi, BaseNAlphabet.Base2); // output=1111101000
output = BaseConverter.ToBaseN(bi, BaseNAlphabet.Base16); // output=3E8
output = BaseConverter.ToBaseN(bi, BaseNAlphabet.Base62); // output=G8

long lg = 1000;
output = BaseConverter.ToBaseN(lg, BaseNAlphabet.Base2); // output=1111101000
output = BaseConverter.ToBaseN(lg, BaseNAlphabet.Base16); // output=3E8
output = BaseConverter.ToBaseN(lg, BaseNAlphabet.Base62); // output=G8

ulong ulg = 1000;
output = BaseConverter.ToBaseN(ulg, BaseNAlphabet.Base2); // output=1111101000
output = BaseConverter.ToBaseN(ulg, BaseNAlphabet.Base16); // output=3E8
output = BaseConverter.ToBaseN(ulg, BaseNAlphabet.Base62); // output=G8

int i = 1000;
output = BaseConverter.ToBaseN(i, BaseNAlphabet.Base2); // output=1111101000
output = BaseConverter.ToBaseN(i, BaseNAlphabet.Base16); // output=3E8
output = BaseConverter.ToBaseN(i, BaseNAlphabet.Base62); // output=G8

uint ui = 1000;
output = BaseConverter.ToBaseN(ui, BaseNAlphabet.Base2); // output=1111101000
output = BaseConverter.ToBaseN(ui, BaseNAlphabet.Base16); // output=3E8
output = BaseConverter.ToBaseN(ui, BaseNAlphabet.Base62); // output=G8

Guid g = new Guid("00000000-0000-0000-0000-0000000003E8");
output = BaseConverter.ToBaseN(g, BaseNAlphabet.Base2); // output=1111101000
output = BaseConverter.ToBaseN(g, BaseNAlphabet.Base16); // output=3E8
output = BaseConverter.ToBaseN(g, BaseNAlphabet.Base62); // output=G8

```

Convert:

```
// Convert a number directly from base-n to base-m
// string output = BaseConverterConvert(string num, BaseNAlphabet sourceA, BaseNAlphabet, outputA);

string output = BaseConverter.Convert("1000", BaseNAlphabet.Base10, BaseNAlphabet.Base36); // output=RS

// Convert a Guid to Base72.
// This is obviously not the easy way to do this.  See the section on extension methods.
Guid g = new Guid("8C55203D-5DCF-4CC3-828C-A841F5EE5668");
string s = BaseConverter.Convert(g.ToString().ToUpper().Replace("-", ""), BaseNAlphabet.Base16, BaseNAlphabet.Base72);

```

## Extension Methods

In order to make the use of extension methods you'll just need the using directive:

```
using Cambia.BaseN;

```

Then the following types:

• BigInteger (may need a reference to System.Numerics for this type)
• Int64
• UInt64
• Int32
• UInt32
• Guid

will all support the following methods:

• Parse
• TryParse
• ToBaseN

Parse:

```
// Signature:
// num.Parse(string sourceNum, BaseNAlphabet sourceA);

// Parses "1111101000" as a base-2 number and returns the value.
BigInteger bi = 0;
BigInteger bi2 = bi.Parse("1111101000", BaseNAlphabet.Base2); // bi=0, bi2=1000
bi = bi.Parse("1111101000", BaseNAlphabet.Base2); // bi=1000

// Behavior is similar for the other supported types:
// Int64, UInt64, Int32, UInt32, Guid

```

TryParse:

```

// Signature:
// bool success = num.TryParse(string sourceNum, BaseNAlphabet sourceA, out T output);
// where T is one of the supported types.

// Attempts to parse "1111101000" as a base-2 number and returns that value in the out parameter.
// If successful, return value is true.  NOTE:  Does not change the value of bi unless bi is
// itself the out parameter passed into the method as follows
bool result = bi.TryParse("1111101000", BaseNAlphabet.Base2, out bi); // if success, bi=1000

// Parse the value into a different variable (bi2).
bi = 0;
result = bi.TryParse("1111101000", BaseNAlphabet.Base2, out bi2); // if success, bi=0, bi2=1000

// Behavior is similar for the other supported types:
// Int64, UInt64, Int32, UInt32, Guid

```

ToBaseN:

```
// Signature:
// string output = num.ToBaseN(BaseNAlphabet targetAlphabet);

// Convert a type to a base-n representation
bi = 1000;
string num = bi.ToBaseN(BaseNAlphabet.Base2); // num=1111101000

// Behavior is similar for the other supported types:
// Int64, UInt64, Int32, UInt32, Guid

```

Quick Math:

```
// Add two binary numbers and represent them as a hex number
int b1 = 0;
int sum =   b1.Parse("1000101011001111", BaseNAlphabet.Base2)
+ b1.Parse("111010100110000", BaseNAlphabet.Base2);
string hexNum = sum.ToBaseN(BaseNAlphabet.Base16); // hexNum = FFFF

```

Compress GUID for URL:

Even though GUIDs in URLs can be extremely useful, they're ugly. At 36 characters they take up a lot of real estate.

https://www.domain.com/8C55203D-5DCF-4CC3-828C-A841F5EE5668

This base-36 representation is less ugly (not much, but a little)

https://www.domain.com/8B377QEPEYB7BPRC75XTAE9NS

This base-62 representation is arguably not less ugly at all, but it's shorter

https://www.domain.com/4GnpMWOg6CP4Fg5Vfqu2Rs

Finally, this base-72 representation is pretty ugly, but it's safe for a URL and it's one character shorter.

https://www.domain.com/DMB!Ii;,n+Yb5l16c!uT!

It seems we have a sweet spot in the base-36 to base-62 range.

```
// Shortening your URL by converting your Guid to a different base
// and then back again is super easy

Guid g = new Guid("8C55203D-5DCF-4CC3-828C-A841F5EE5668");

// base-36
string shortGuid = g.ToBaseN(BaseNAlphabet.Base36);
g = g.Parse(shortGuid, BaseNAlphabet.Base36);

// base-62
shortGuid = g.ToBaseN(BaseNAlphabet.Base62);
g = g.Parse(shortGuid, BaseNAlphabet.Base62);

// base-72 safe
shortGuid = g.ToBaseN(BaseNAlphabet.Base72_Safe);
g = g.Parse(shortGuid, BaseNAlphabet.Base72_Safe);

```

Version: 5.1.20190301.2112