【问题标题】:Visual basic substitution cipherVisual Basic 替换密码
【发布时间】:2013-04-13 10:17:25
【问题描述】:

我正在尝试使用 Visual Basic 创建替换密码。我是编程新手,正在苦苦挣扎,所以请多多支持。

密码应该执行以下操作:

  1. 请求用户加密消息。
  2. 要求用户提供密钥(或要求系统生成密钥,以更容易编码为准)。
  3. 使用密钥加密消息。
  4. 返回加密消息。

例子:

  • 消息 = 你好
  • 字母:“abcdefghijklmnopqrstuvwxyz”
  • 键:“kxgtlmpqbwcenderfahjusviyoz”
  • 返回加密消息。

我需要帮助的主要部分是 2 和 3。我需要知道解决此问题的步骤(英语或语法),然后我可以尝试自己编写代码。如果你有一个很好的例子。

请注意,我并不是在寻求有关如何创建凯撒密码的帮助。此处的替换密码会将每个字母替换为另一个字符(这是密钥)。

谢谢。

【问题讨论】:

  • 在不知道您在哪里的情况下很难提供帮助。开始之前有用的概念是数组、字典、循环、随机、StringBuilder。假设您从用户那里获取密钥是一个验证问题,而不是 UI 问题。如果您还不了解上述内容,则需要退后一步并查找它们。 PS你知道这种密码很容易破解吗?

标签: vb.net substitution encryption


【解决方案1】:

我不懂任何 Visual Basic,所以我不能给你代码,但既然你说用英文解释是可以接受的,让我试着把你的步骤分解成更小的步骤,你可能会觉得更容易实施:

  1. 首先,您需要从用户那里获取消息,例如要求他们输入(或复制和粘贴)字符串。我假设你知道如何在 VB 中做到这一点,因为我不知道。

  2. 接下来,对密钥执行相同的操作。 (您可能应该构建您的程序,以便如果密钥无效(可以在下一步中方便地检查),您可以循环回到这一步并要求一个新密钥。)您可能希望立即转换全部小写(或全部大写)的键,并检查它是否正好有 26 个字符。

  3. 接下来,您应该将键字符串转换为要替换哪些字母的映射。 (这可能不是必需的:有些语言提供现成的字符串音译函数,比如 PHP 的strtr,可以直接使用这样的关键字符串,但我假设你想这样做“从地面”。)这可能有点涉及,所以我将把它分解成更小的步骤:

    • 首先,您需要创建地图对象。 VB 希望能提供某种方式来表示从字符到字符(或从单字母字符串到单字母字符串)的映射,可能称为“字典”或“哈希表”。

    • 接下来,您需要遍历密钥字符串的字符。通常有两种方法可以做到这一点:将键字符串拆分为字符列表(或单字母子字符串)并循环遍历,或者仅使用从 1 运行的索引 i 循环到字符串的长度并在每次迭代时从字符串中提取第 i 个字符。无论哪种情况,您还需要跟踪(或计算)字母表中的第 i 个字母。

    • 现在,假设您现在有两个变量:k 包含密钥字符串中的第 i 个字母,a 包含i - 字母表中的第一个字母。现在,只需将条目映射 ka 插入到您的字典/哈希表/在 VB 中调用的任何内容中。如果您的输入消息可以包含大写和小写字母,您应该为 ka 的大写和小写版本插入一个映射条目。此外,对于解密,只需交换 ka 以便字典从 a 映射到 k

      • 这也是检查密钥有效性的好时机:在插入从 ka 的映射条目之前,检查是否存在“ t 已经是从 k 到其他字母的映射条目。如果有,中止,让用户知道密钥无效并要求新密钥。这将确保密钥没有重复的字母,这(连同它的 26 个字母长)确保它是字母表的有效排列。哦,你显然还应该检查 k 实际上是一个字母,而不是一个标点符号。

      • (对于解码,这有点棘手;您可能想要构建两个地图,每个方向一个,这样您就可以使用 k-to-a 用于有效性检查的映射。)

  4. 最后,您可以使用您构建的映射对消息进行编码:只需遍历消息中的每个字符,检查是否在映射中找到它,如果是,将其替换为映射到的字符. (如果您无法修改原始消息字符串,您可以将每个输出字符附加到一个字符列表中,然后最后将它们全部连接成一个字符串。或者只是从一个空的输出字符串开始,然后直接将每个输出字符附加到它上面, 尽管 可能 效率较低,这取决于在 VB 中如何实现字符串操作,而不是先构建一个列表。)

【讨论】:

  • 太棒了。我非常感谢您的帮助和时间。我现在会继续努力的:)谢谢。
【解决方案2】:

【讨论】:

  • 如果 OP 想要进行真正的(现代的、安全的)加密,这些都是很好的参考。但是,如果他们只是想实现一个替代密码来获得乐趣,或者可能是为了加密谜题,那么这些链接将不是很相关。 (此外,仅包含链接列表的答案在 Stack Overflow 上通常被认为不是很好。)
  • 感谢 Ilmari 的提醒,不胜感激。也许我应该告诉他先用谷歌搜索一下;-)
  • 感谢您的链接。有用的提示:)
【解决方案3】:

假设您的字母表的键长度相同, 您可以执行 FOR 循环来检查字符串的每个字符(该字符与您的键的关系)。

例如,您的消息“你好”。

这不是实际代码,只是为了演示您所要求的概念:

for each letter in message
    position_in_alphabet = current_letter
    cipher_letter = key(position_in_alphabet)
    append cipher_letter to cipher_message

例如,“你好”是 5 个字符。所以这个循环会循环5次。 字母表中的位置是(8th, 5th, 12th, 12th, 15th)。 您插入与密钥相关的那些,您会得到“qlnnr”(或密钥指示)。

把它们放在一起,它看起来像:

Dim _message As String = "hello"
Const _plain As String = "abcdefghijklmnopqrstuvwxyz"
Const _key As String = "kxgtlmpqbwcnderfahjusviyoz"
Dim charPos As Integer = 0
Dim Cipher As String = ""

For i = 0 To _message.Length - 1
    charPos = _plain.IndexOf(_message(i))
    Cipher = Cipher & _key(charPos)
Next i

反过来,查找密码相对于密钥的位置,然后将其放入明文字典中,如下所示:

Dim _cipher As String = "qlnnr"
Const _plain As String = "abcdefghijklmnopqrstuvwxyz"
Const _key As String = "kxgtlmpqbwcnderfahjusviyoz"
Dim charPos As Integer = 0
Dim Message As String = ""

For i = 0 To _message.Length - 1
    charPos = _key.IndexOf(_cipher(i))
    Message = Message & _plain(charPos)
Next i

【讨论】: