Skip to content

Instantly share code, notes, and snippets.

@shaunsales
Created December 23, 2018 12:10
Show Gist options
  • Save shaunsales/c9a5020627306fb74b0668d225b8aee8 to your computer and use it in GitHub Desktop.
Save shaunsales/c9a5020627306fb74b0668d225b8aee8 to your computer and use it in GitHub Desktop.
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