增加字节数组中的字符

Increment char in byte array

我正在用以下内容预填充一个字节数组:

 private static byte[] idBuffer = ASCIIEncoding.Default.GetBytes("A" + DateTime.Now.ToString("yy") + DateTime.Now.DayOfYear + "0000001");

字节数组中的“0000001”部分是我的 ID 部分,我想在每次调用 "Increment" 方法时用 ASCII 字符 0-1A-S 递增。

例如,增量序列样本为:

000000S
...
00000S0
00000S1
...
00000SS
...
0000S00
...
0000S99
0000S9A
等等

我在想出正确的 algorithm/state 机器来正确递增字符时遇到一些问题。

现在我预填一个字符 table:

private static byte[] charCodes = new byte[] { 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 80, 81, 82, 83};

以及我为此在状态机上的粗略尝试,但它只让我获得了第二名:

if (idBuffer[bufPosition] < 83)
{
    idBuffer[bufPosition] = charCodes[charCodePosition];
    charCodePosition++;
}
else
{
    if (idBuffer[bufPosition - 1] == 48)
    {
        for (int i = bufPosition; i < idBuffer.Length; i++)
            idBuffer[i] = 48;

        idBuffer[bufPosition - 1] = charCodes[charCodePosition2];
        charCodePosition2++;
    }
    else
    {
        charCodePosition2++;
        idBuffer[bufPosition - 1] = charCodes[charCodePosition2];
    }

    charCodePosition = 0;
}

我确信有一种我想不到的更优雅的方法来做到这一点 - 理想情况下,如果有人知道如何使用不安全的方法来做到这一点 code/pointers,那就更好了!

其实很简单:

  1. 从最后一个元素开始。
  2. 加一个。
  3. 如果您现在有 '0'+10 (58),请将其调整为 'A' (65)。
  4. 如果你有除'T'以外的任何东西(懒得查ASCII码)你就完了。
  5. 调整为'0' (48)。
  6. 向左移动一个元素并从第 2 步开始重复。

基于,事实上你想要很酷的(假设目标更喜欢unsafe)代码和固定大小的数字你可以将整个代码展开到简单的状态机中:

{number-to-add, char} -> {incremented char, carry}

'A'-'C' 的近似代码为 0,1,3。如果表合并为一个表(即将 char 和索引合并为单个 uint 带有位移的值)

,可能会稍微简化
char[2,256] incrementedChar = new char[2,256]{
      {...64 0..., 'A', 'B', 'C', more 0 }, // A+0 = A, 
      {...64 0..., 'B', 'C', 'A', more 0 }};// A+1 = B, .., C+1 = A+carry

int[2,256] carryTable = new int[2,256]{
      {...64 0..., 0, 0, 0, more 0 }, // adding 0 never carry 
      {...64 0..., 0, 0, 1, more 0 }};// carry when adding 1 to `C`

var chars = new[] {'A','A', 'A', 'C'};
int carry = 1; // adding 1 to the last digit
char current;
// unrolled loop from end to start. Adjust indexes if it is not in the beginning.

current = incrementedChar[carry, chars[3]];
carry = carryTable[carry, chars[3]];
chars[3] = current;

current = incrementedChar[carry, chars[2]];
carry = carryTable[carry, chars[2]];
chars[2] = current;

current = incrementedChar[carry, chars[1]];
carry = carryTable[carry, chars[1]];
chars[1] = current;

current = incrementedChar[carry, chars[0]];
carry = carryTable[carry, chars[0]];
chars[0] = current;