【问题标题】:substitution cipher case sensitive using c#使用 c# 替换密码区分大小写
【发布时间】:2016-02-29 06:53:59
【问题描述】:

我想制作一种加密方法,它可以在纯文本变量中接受大写和小写,比如(“Hello World)它只接受小写字母,请帮助我,我想 它工作正常,只有小写字母作为输入,请帮助我

            using System;

        class SubstitutionCipher
        {
           static void Main()
           {
              string key = "jfkgotmyvhspcandxlrwebquiz";
              string plainText = "the quick brown fox jumps over the lazy dog";
              string cipherText = Encrypt(plainText, key);
              string decryptedText = Decrypt(cipherText, key);
              Console.WriteLine("Plain     : {0}", plainText);
              Console.WriteLine("Encrypted : {0}", cipherText);
              Console.WriteLine("Decrypted : {0}", plainText);
              Console.ReadKey();
           }
    //encryption method 
           static string Encrypt(string plainText, string key)
           {
              char[] chars = new char[plainText.Length];
              for(int i = 0; i < plainText.Length; i++)
              {
                 if (plainText[i] == ' ')
                 {
                    chars[i] = ' ';
                 }   
                 else
                 {
                    int j = plainText[i] - 97;
                    chars[i] = key[j];
                 }
              }
              return new string(chars);
           }
//decryption method
           static string Decrypt(string cipherText, string key)
           {
              char[] chars = new char[cipherText.Length];
              for(int i = 0; i < cipherText.Length; i++)
              {
                 if (cipherText[i] == ' ')
                 {
                    chars[i] = ' ';
                 }   
                 else
                 {
                    int j = key.IndexOf(cipherText[i]) - 97;
                    chars[i] = (char)j;
                 }
              }
              return new string(chars);
           } 
        }

【问题讨论】:

    标签: c# encryption substitution


    【解决方案1】:

    这是一个有趣的问题,尤其是在一般情况中。所以我们有

    1. 密钥中的字符,这些字符应加密(例如aj
    2. 不在键中的字符,应该跳过这些字符(例如空格

    为了高效,让我们设计一个Encryptor\DecryptorDictionary&lt;Char, Char&gt;,为了做到这一点,我们应该对key中的字符进行排序并进行对应; 例如对于

      key        = "jfkgo"
      sorted key = "fgjko"
    

    这对将是

      {j, f} // when encrypting "j" becomes "f", on decryption "f" turns into "j"
      {f, g}
      {k, j}
      {g, k}
      {o, o}
    

    当读取从左到右我们有一个加密器,当读取从右到左一个解密器

    private static Dictionary<Char, Char> Encryptor(String key) {
      Char[] data = key.ToArray();
      Char[] sorted = data.OrderBy(c => c).ToArray();
    
      return data
        .Zip(sorted, (plain, encrypted) => new {
             Plain = plain,
             Encrypted = encrypted
         })
        .ToDictionary(item => item.Plain, item => item.Encrypted);
    }
    
    // Note, that Decryptor is the same as Encryptor by for the last line
    private static Dictionary<Char, Char> Decryptor(String key) {
      Char[] data = key.ToArray();
      Char[] sorted = data.OrderBy(c => c).ToArray();
    
      return data
        .Zip(sorted, (plain, encrypted) => new {
          Plain = plain,
          Encrypted = encrypted
        })
        .ToDictionary(item => item.Encrypted, item => item.Plain);
    }
    

    现在,很容易实现加密和解密方法

    private static String Encrypt(String source, String key) {
      var dict = Encryptor(key);
    
      StringBuilder Sb = new StringBuilder(source.Length);
    
      Char sub;
    
      foreach (var ch in source)
        if (dict.TryGetValue(ch, out sub))
          Sb.Append(sub);
        else
          Sb.Append(ch);
    
      return Sb.ToString();
    }
    
     // Note, that Decryptor is the same as Encryptor by for the first line
    private static String Decrypt(String source, String key) {
      var dict = Decryptor(key);
    
      StringBuilder Sb = new StringBuilder(source.Length);
    
      Char sub;
    
      foreach (var ch in source)
        if (dict.TryGetValue(ch, out sub))
          Sb.Append(sub);
        else
          Sb.Append(ch);
    
      return Sb.ToString();
    }
    

    一个小测试

     // For test, let capital letters mmimic the small ones
     string key = "jfkgotmyvhspcandxlrwebquiz" + "jfkgotmyvhspcandxlrwebquiz".ToUpper();
    
     string plainText = "The Quick Brown Fox Jumps Over The Lazy Dog!";
     string cipherText = Encrypt(plainText, key);
     string decryptedText = Decrypt(cipherText, key);
    
     Console.WriteLine("Plain     : {0}", plainText);
     Console.WriteLine("Encrypted : {0}", cipherText);
     Console.WriteLine("Decrypted : {0}", plainText);
    

    【讨论】:

      【解决方案2】:

      您要减去“a”,这仅适用于小写字符。您应该检查它是大写还是小写,然后分别减去 A 或 a。此外,您可以直接使用 'a' 或 'A' 来获得 int 等效的字符。

      我的意思是在你的 else 语句中使用它来解密和加密:

          static string Encrypt(string plainText, string key)
          {
              char[] chars = new char[plainText.Length];
              for (int i = 0; i < plainText.Length; i++)
              {
                  if (plainText[i] == ' ')
                  {
                      chars[i] = ' ';
                  }
                  else if (Char.IsUpper(plainText[i]))
                  {
                      int j = plainText[i] - 'A';
                      chars[i] = key[j];
                  }
                  else
                  {
                      int j = plainText[i] - 'a';
                      chars[i] = key[j];
                  }
              }
              return new string(chars);
      
          static string Decrypt(string cipherText, string key)
          {
              char[] chars = new char[cipherText.Length];
              for (int i = 0; i < cipherText.Length; i++)
              {
                  if (cipherText[i] == ' ')
                  {
                      chars[i] = ' ';
                  }
                  else if (Char.IsUpper(cipherText[i]))
                  {
                      int j = key.IndexOf(cipherText[i]) - 'A';
                      chars[i] = (char)j;
                  }
                  else
                  {
                      int j = key.IndexOf(cipherText[i]) - 'a';
                      chars[i] = (char)j;
                  }
              }
              return new string(chars);
          }
      

      或分别用于加密和解密的简短版本:

                  else 
                  {
                      int j = Char.IsUpper(plainText[i]) ? plainText[i] - 'A' : plainText[i] - 'a';
                      chars[i] = key[j];
                  }
      
                  else
                  {
                      int j = Char.IsUpper(cipherText[i]) ? key.IndexOf(cipherText[i]) - 'A' :  key.IndexOf(cipherText[i]) - 'a';
                      chars[i] = (char)j;
                  }
      

      编辑:

      好的,我认为算法已经完成了,我刚刚修复了会导致异常的部分。但是,您是:

      a) 不考虑哪个字母大写和 b) 没有可用的解密器。 (我认为它有效,但是您的主要方法将明文结果作为解密消息)。

      要修复您的解密器,您需要在加密器上添加一种存储大写字母的方法。您可以对它进行更复杂的处理,但目前,我们将其加密为密文上的大写字母。

          static string Encrypt(string plainText, string key)
          {
              char[] chars = new char[plainText.Length];
              for (int i = 0; i < plainText.Length; i++)
              {
                  if (plainText[i] == ' ')
                  {
                      chars[i] = ' ';
                  }
                  else 
                  {
                      int j = Char.IsUpper(plainText[i]) ? plainText[i] - 'A' : plainText[i] - 'a';
                      chars[i] = Char.IsUpper(plainText[i]) ? Char.ToUpper(key[j]) : key[j];
                  }
              }
              return new string(chars);
      

      要解密,您应该在密钥上找到它作为小写字符,但输出为大写字符。

          static string Decrypt(string cipherText, string key)
          {
              char[] chars = new char[cipherText.Length];
              for (int i = 0; i < cipherText.Length; i++)
              {
                  if (cipherText[i] == ' ')
                  {
                      chars[i] = ' ';
                  }
                  else
                  {
                      int j = Char.IsUpper(cipherText[i]) ? key.IndexOf(Char.ToLower((char)cipherText[i])) + 'a' : key.IndexOf(cipherText[i]) + 'a';
                      chars[i] = Char.IsUpper(cipherText[i]) ? Char.ToUpper((char)j) : (char)j;
                  }
              }
              return new string(chars);
          }
      

      【讨论】:

      • 使用您的方法后,解密方法无法正常工作,请问先生是什么问题?这是我的代码
      • @HoneyBuny 显然解密功能一开始就不起作用。哼。我正在更新我的答案。
      • 先生,它不再工作了 :( 加密工作完美,但解密方法仍然无法工作,它给出了结果 ,,,,,
      • 这适用于所有小写键。您必须调整大写或混合键。
      • @HoneyBuny 简而言之使用你原来的string key = "jfkgotmyvhspcandxlrwebquiz";
      猜你喜欢
      • 2010-10-29
      • 2013-12-13
      • 1970-01-01
      • 2018-01-06
      • 2014-02-16
      • 1970-01-01
      • 2013-10-19
      • 2014-04-11
      • 2019-09-16
      相关资源
      最近更新 更多