代码之家  ›  专栏  ›  技术社区  ›  jakogut

顺序密钥生成

  •  0
  • jakogut  · 技术社区  · 16 年前

    现在,我正在做一个需要顺序文本键生成的项目。我需要在密钥生成器中植入一个与某个密钥对应的整数,构造函数将其转换为密钥。

    我的键生成器重载递增运算符,以便字符串直接递增,而不是像我以前所做的那样,递增索引值,然后将索引转换为要生成的每个键的键。

    我的问题是,我有一个有限的字符集,我想使用生成关键点。我必须在关键点中找到我想要增加的字符,找出它在我的字符集中的位置,找到集中的下一个字符,然后用集中的下一个字符替换关键点中的字符。

    这是我的密码:

    // Not the full charset
    std::string charset = "abcdefghijklmnopqrstuvwxyz0123456789"; 
    std::string key;
    
    key.push_back(charset[0]);
    
    for(unsigned int place = 0; place < key.length(); place++)
    {
        if(key[place] == charset[charset.length() - 1])
        {
            // Overflow, reset char at place
            key[place] = charset[0];
    
            if((key.length() - 1) < (place + 1))
            {
                // Carry, no space, insert char
                key.insert(key.begin(), charset[0]);
                break;
            }
            else
            {
                // Space available, increment next char
                continue;
            }
        }
        else
        {
            // Increment char at place
            key[place] = charset[charset.find(key[place]) + 1];
            break;
        }
    }
    

    5 回复  |  直到 16 年前
        1
  •  1
  •   Asher Dunn    16 年前

    您可以存储一个与键长度相同的向量,其中向量中的每个元素都是键中相应字符的字符集中的索引。

    例如,如果 key[0] 然后是“c” thisVector[0] 将为2,因为“c”是字符集中的第三个字符。

    然后,所有操作都将在该整数向量上执行,从而消除了 find

        2
  •  3
  •   Mark Ransom    16 年前

    与其进行查找,不如使用反向转换数组?数组索引将是字符,数组中的值将是其数值(或索引到另一个数组)。

    key[place] = charset[reverse_charset[key[place]] + 1];
    
        3
  •  2
  •   Terry Mahaffey    16 年前

    您要做的是将密钥视为无符号整数,并将正在分发的“字符串”视为该密钥的基36(a-z+0-9)表示形式。

    要转换,请执行与将任何整数转换为十六进制表示法相同的操作,但在模数学中交换36而不是16。我将把这作为练习留给读者。:)

        4
  •  1
  •   Permaquid    16 年前

    我不确定我是否完全理解您想要做什么,但这里有一个小控制台程序,它使用您的字符集作为数字,以36为基数打印出36*36*36个3位数的键序列。所以它从aaa开始到999结束。

    #include <stdio.h>
    typedef int Number;
    const size_t N = 3;
    size_t B = 36;
    Number key[N] = {0};
    bool carry = false;
    char A[] = "abcdefghifjlmnopqrstuvwxyz0123456789";
    
    void incr(size_t i)
    {
        if(!carry)
        {
            return;
        }
        ++key[i];
        if(key[i] == B)
        {
            key[i] = 0;
        }
        else
        {
            carry = false;
        }
    }
    
    void Incr()
    {
        carry = true;
        size_t i = 0;
        while(carry)
        {
            incr(i++);
        }
    }
    
    void Print()
    {
        for(int i = N - 1; i >= 0; --i)
        {
            printf("%c", A[key[i]]);
        }
        printf("\n");
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        for(int i = 0; i < B * B * B; ++i)
        {
            Print();
            Incr();
    
        }
        return 0;
    }
    
        5
  •  0
  •   aib    16 年前

    也许您最好将索引转换为字符集,然后在需要时将它们转换为实际字符?

    这样可以节省在字符集中搜索字符的开销。将字符集索引转换为字符将是一个常数时间操作,而不是相反的操作。

    将密钥存储为整数0~N-1的向量,其中N是字符集的长度。仅当需要时,即在增量之后,才将这些整数转换为实际字符。