c# - Vigenere Square Lookup(使用字符串数组)

标签 c# algorithm encryption pseudocode vigenere

Vigenere 密码据说易于使用(嗯,在某种程度上),但是当将其直接转换为程序代码时,情况就完全不同了。显然。

这是维吉尼亚广场: Vigenere Square from Wikipedia

假设我有一种方法可以使用 Vigenere Square 密码加密文本,同时仍保留空格和特殊字符(或其中的大部分字符)。

static string EncryptedText(string plaintext, string keyword)
{
    string tempStore = "";
    string KeyToUse = ExpandKey(RemoveAllNonAlpha(plaintext), keyword);
    string[] tempList;
    int iSelector = 0;

    for (int ii = 0; ii < RemoveAllNonAlpha(plaintext).Length; ii++)
    {
        tempList = GetNewAlphaList(KeyToUse[ii].ToString());
        if (RemoveAllNonAlpha(plaintext)[ii].ToString() != " ")
        {
            iSelector = NeverOver26(GetNumericFromLetter(RemoveAllNonAlpha(plaintext)[ii].ToString())) - 1;

            tempStore += tempList[iSelector].ToLower();
        }
        else
        {
            tempStore += " ";
        }
    }

    return ReplaceAllNonAlpha(tempStore, plaintext);
}

如果我们假设对于上面的情况,下面的函数是这样的......

string ExpandKey(string input) => Lengthen the key until it matches the plaintext.

string RemoveAllNonAlpha(string input) => Basically remove anything that is not an alphabet. Uses Regex Replace.

int GetNumericFromLetter(string char) => Just converts a letter to a number, with A = 1, and Z = 26. Adapted version of this accepted answer.

string ReplaceAllNonAlpha(string processed, string original) => Basically it just checks the original string, and then replaces all the non alphabetical characters. It's mainly using a regex string to check if a character is not an alphabet.

int NeverOver26(int input) => Basically it just subtracts 26 from the value whenever it goes over 26.

string[] GetNewAlphaList(string char) => Generates a column or row of the vigenere cipher to lookup from, with the letter passed in being the first letter in the array. For example, if the passed letter is "L", then it returns { "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K" }.

现在,上面的代码片段被发现可以完美地工作,可以说是从字面上翻译自人类使用维吉尼亚方 table 的方式。

然而,解密方法似乎并不喜欢这种方法,虽然:

static string DecryptedText(string ciphertext, string keyword)
{
    //Broken, non deciphering
    string tempStore = "";
    string KeyToUse = ExpandKey(RemoveAllNonAlpha(ciphertext), keyword);
    string[] tempList;

    for (int ii = 0; ii < RemoveAllNonAlpha(ciphertext).Length; ii++)
    {
        tempList = GetNewAlphaList(RemoveAllNonAlpha(ciphertext)[ii].ToString());

        for (int iii = 0; iii < tempList.Length; iii++)
        {
            if (tempList[iii].ToString().ToLower() == KeyToUse[ii].ToString().ToLower())
            {
                tempStore+= GetAlphaFromNumber(iii).ToLower();
                break;
            }
        }
    }

    return ReplaceAllNonAlpha(tempStore, ciphertext);
}

在(未按预期工作)解密方法中,我们可以看到它使用了与加密方法大部分相同的功能,除了...

string GetAlphaFromNumber(int input) => Does the exact opposite of GetNumericFromLetter() Adapted version of this accepted answer.

已确定问题出在解密方法本身的第二个 for 循环中。这是一种原始查找过程,它只是在与维吉尼亚广场表的行/列相对应的字符串数组中查找。

是逻辑有问题,还是代码本身有问题?伪代码没问题,我承认我不太确定如何使用Vigenere 方表转换为伪代码(然后最终转换为我正在使用的选择语言)

请注意,我知道这些问题,我不是在寻找如何去做,而是在寻找我哪里出错了:

我想我的问题与这个问题非常相似,尽管我怀疑问题是否相同:


测试加密...

Input: ATTACK ON DAWN. LOL

Keyword: LEMON

Output: lxfopv ef rnhr. xcy


测试解密...

Input: lxfopv ef rnhr. xcy

Keyword: LEMON

Output: ahhayq ah xaen. pmp

检查结果使用:http://planetcalc.com/2468/

最佳答案

原来我一开始就用错了查表的方法。我的程序编码没有任何问题,因为它按预期工作。这只是它查找值的方式,或者换句话说,错误的逻辑。下面是修改后的解密方法代码,现在可以正常工作了:

internal static string DecryptedText(string ciphertext, string keyword)
{
    string tempStore = "";
    string KeyToUse = ExpandKey(RemoveAllNonAlpha(ciphertext), keyword);
    string[] tempList;
    int iSelector = 0;

    for (int ii = 0; ii < RemoveAllNonAlpha(ciphertext).Length; ii++)
    {
        tempList = GetNewAlphaList(KeyToUse[ii].ToString());

        for (int iii = 0; iii < tempList.Length; iii++)
        {
            ////seperated the two to verify they were not returning the wrong values
            //string FromList = tempList[iii].ToString().ToLower();
            //string FromCipher = RemoveAllNonAlpha(ciphertext)[ii].ToString().ToLower();

            if (tempList[iii].ToString().ToLower() ==  RemoveAllNonAlpha(ciphertext)[ii].ToString().ToLower())//if (FromList == FromCipher)
            {
                tempStore += GetAlphaFromNumber(iii).ToLower();
                break;
            }
        }
    }
        
    return ReplaceAllNonAlpha(tempStore, ciphertext);
}

测试加密...

Input: this is just a simple test. complete with punctuations galore, wohoo!

Keyword: stackoverflowisthebest

Output: laiu sg eyjy l geuhel xfwl. vgfpnohz azys dqvumbeumggk zanyfz, afmzc!


测试解密...

Input: laiu sg eyjy l geuhel xfwl. vgfpnohz azys dqvumbeumggk zanyfz, afmzc!

Keyword: stackoverflowisthebest

Output: this is just a simple test. complete with punctuations galore, wohoo!


我想是时候尝试找到一种方法让它在转换后也能保留大写了。

关于c# - Vigenere Square Lookup(使用字符串数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33807658/

相关文章:

algorithm - Gecko(或任何其他布局引擎)如何呈现文档/页面?

c# - 我如何在 .NET 中表示 URN(统一资源名称)以便 Equals 按预期工作

arrays - 根据第一个数组的索引查找第二个数组的值

c# - 无法将类型 'System.DateTime?' 隐式转换为 'System.DateTime' 。存在显式转换

algorithm - 为技术面试(周一)复习算法的最快方法是什么?

php - iOS - Swift 中的密码加密

java - Java AES 加密是否符合 FIPS 140-2?

JAVA AES 256 和公钥加密

c# - 将实际记录作为属性包含在 Filehelpers 记录对象中

c# - 具有相似分隔符的字符串拆分 C#