Created
December 23, 2018 12:10
-
-
Save shaunsales/c9a5020627306fb74b0668d225b8aee8 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; | |
using System.Text; | |
namespace MatchingEngine.Utils | |
{ | |
internal static class SymbolConversion | |
{ | |
/// <summary> | |
/// Converts a symbol matching the format AAA-1234 to an integer. | |
/// Stores the letter component in the most significant two bytes and the numeric component in the least significant two bytes. | |
/// </summary> | |
/// <param name="symbol">Symbol in the AAA-1234 format.</param> | |
/// <returns>A positive integer representing the input symbol.</returns> | |
public static int ToInt(string symbol) | |
{ | |
if (symbol == null || symbol.Length != 8) | |
{ | |
throw new ArgumentException(symbol == null ? "Symbol must not be null." : "Symbol must be exactly 8 characters."); | |
} | |
var parts = symbol.Split("-"); | |
if (parts.Length != 2 || parts[0].Length != 3 || parts[1].Length != 4) | |
{ | |
throw new ArgumentException("Symbol is not in the correct format. Must follow the pattern AAA-1234."); | |
} | |
var rhs = int.Parse(parts[1]); | |
if (rhs < 1000) | |
{ | |
throw new ArgumentException("Symbol numeric component must be greater than 1000."); | |
} | |
var lhs = ToBase10(parts[0]) & 0xFFFF; | |
rhs = rhs & 0xFFFF; | |
return (lhs << 16) | rhs; | |
} | |
/// <summary> | |
/// Converts a an integer into a symbol using Base10 to Base26 for the letter component. The numeric component is stored as a short in the least significant two bytes. | |
/// </summary> | |
/// <param name="instrument">A positive integer that has been correctly encoded.</param> | |
/// <returns>Symbol in the AAA-1234 format.</returns> | |
public static string ToSymbol(int instrument) | |
{ | |
if (instrument <= 0) | |
{ | |
throw new ArgumentException("Symbol integer must be greater than zero."); | |
} | |
var lhs = ToBase26((instrument >> 16) & 0x0000FFFF); | |
var rhs = instrument & 0x0000FFFF; | |
return $"{lhs}-{rhs}"; | |
} | |
private static int ToBase10(string base26) | |
{ | |
var result = 0; | |
for (var i = 0; i < base26.Length; i++) | |
{ | |
result += (base26[i] - 64) * (int)Math.Pow(26, base26.Length - (i + 1)); | |
} | |
return result; | |
} | |
private static string ToBase26(int number) | |
{ | |
var result = new StringBuilder(8); | |
while (number > 0) | |
{ | |
number--; | |
var remainder = number % 26; | |
result.Insert(0, (char)(remainder + 65)); | |
number = (number - remainder) / 26; | |
} | |
return result.ToString(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment