using System;
using System.Collections.Generic;
namespace AutoNumber
{
public class AutoNumber
{
private static readonly int DecLength = (int)'Z' - (int)'A' + 1 - 3 + 10; // ILOを除くA〜Zと0〜9の33
private static readonly int OffsetNum0 = (int)'0'; // 48
private static readonly int OffsetNum1= (int)'A' - 10; // 55
#region 33進数から10進数
public static int ToDecimal(string source)
{
return ConvertString(0, new Queue<char>(source.ToCharArray()));
}
private static int ConvertString(int ret, Queue<char> chars)
{
if (chars.Count == 0)
{
return ret;
}
else
{
char c = chars.Dequeue();
return ConvertString(CalcDecimal(c, chars.Count) + ret, chars);
}
}
private static int CalcDecimal(char c, int times)
{
int offsetNum = 0;
switch (c)
{
case char s when s < 'A':
offsetNum = OffsetNum0;
break;
case char s when s < 'I':
offsetNum = OffsetNum1;
break;
case char s when s < 'L':
offsetNum = OffsetNum1 + 1;
break;
case char s when s < 'O':
offsetNum = OffsetNum1 + 2;
break;
case char s when s <= 'Z':
offsetNum = OffsetNum1 + 3;
break;
default:
offsetNum = OffsetNum0;
break;
}
return (int)Math.Pow(DecLength, times) * ((int)c - offsetNum);
}
#endregion
#region 10進数から33進数
public static string To33Decimal(int source)
{
return ConvertNumber(string.Empty, source);
}
public static string GetNext(string source)
{
return To33Decimal(ToDecimal(source) + 1);
}
private static string ToChar(int n)
{
int offsetNum = 0;
switch (n)
{
case int m when m < 10:
offsetNum = OffsetNum0;
break;
case int m when m < 18:
offsetNum = OffsetNum1;
break;
case int m when m < 20:
offsetNum = OffsetNum1 + 1;
break;
case int m when m < 22:
offsetNum = OffsetNum1 + 2;
break;
case int m when m < 33:
offsetNum = OffsetNum1 + 3;
break;
default:
offsetNum = OffsetNum0 - DecLength;
break;
}
return ((char)(n + offsetNum)).ToString();
}
private static string ConvertNumber(string ret, int n)
{
if (n == 0)
{
return string.IsNullOrEmpty(ret) ? "0" : ret;
}
else
{
int quo = n / DecLength;
int rem = n % DecLength;
if (rem == 0)
{
rem = DecLength;
}
return ConvertNumber(ToChar(rem) + ret, quo);
}
}
#endregion
}
}