标题:关于C#编写波雷费密码的困惑
只看楼主
GLaDOS
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2011-4-20
结帖率:100%
已结贴  问题点数:20 回复次数:8 
关于C#编写波雷费密码的困惑
本人初学C#编程,新的不能再新了。现在遇到了第一个难题,是关于使用C#模拟波雷费密码的。
对于如何编写算法小弟百思不得其解,遂向论坛各位高手求助。我会写上目前我摸索到的和我的想法。

首先什么是波雷费密码:
波雷费密码是一种对称式密码,是首种双字母取代的加密法。   
在第二次布尔战争和第一次世界大战,英军用了它;在二战,澳大利亚人也用了。波雷费密码所用的工具很少,而且很快便能加密讯息。
它主要用来加密重要而又不关键的讯息。当时,敌军的密码分析员很快解出密码,可惜得的讯息都不重要。现时,波雷费密码被视为十分不安全的。

如何加密:
1选取一个英文字作密匙。除去重复出现的字母。将密匙的字母逐个逐个加入5×5的矩阵内,剩下的空间将未加入的英文字母依a-z的顺序加入。(将Q去除,或将I和J视作同一字。)   
2将要加密的讯息分成两个一组。若组内的字母相同,将X(或Q)加到该组的第一个字母后,重新分组。若剩下一个字,也加入X字。   
3在每组中,找出两个字母在矩阵中的地方。
 若两个字母不同行也不同列,在矩阵中找出另外两个字母,使这四个字母成为一个长方形的四个角。   
 若两个字母同行,取这两个字母右方的字母(若字母在最右方则取最左方的字母)。   
 若两个字母同列,取这两个字母下方的字母(若字母在最下方则取最上方的字母)。   
4新找到的两个字母就是原本的两个字母加密的结果。

举个例子:
取“playfair example”为密匙,得

P L A Y F
I R E X M
B C D G H
J K N O S
T U V W Z
要加密的讯息为 “Hide the gold in the tree stump”。

明文处理为:HI DE TH EG OL DI NT HE TR EX ES TU MP
就会得到“BM ND ZB XD KY BV JV DM UI XM MN UV IF”。

我现在的进度是使用写好的明文和密钥来制作密文

才开了小头,感觉漏洞百出,不知如何是好了。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;//In order to use Regex.Replace method


namespace assigment1
{
    class Encrypt
    {
        public string Keypad(string key)//处理密钥KEY的方法
        {
            string Firststep;
            Firststep = key.ToUpper();//密钥所有字母变作大写
            string strkey = Regex.Replace(Firststep, "[^A-Z]+","");//对比KEY中的字母,随后添加A-Z的字母,做成字符串。
            return strkey = strkey.Replace("J", "I");//替换密钥中的J为I,返回处理的密钥。
        }
        public string Messagepad(string Message)//处理明文的方法,检查若有重复字母,添加“X”,返回处理好的明文。(好像漏掉了只有一个字的词组尾添加“X”的命令,如何实现呢?)
        {
            string paddedStr = "";
            if (Message.Length > 0)
            {
                int i = 0;
                char fc, sc;
                while (i < Message.Length)
                {
                    fc = Message[i];
                    i++;
                    if (i == Message.Length || Message[i] == fc)
                    {
                        sc = 'X';
                    }
                    else
                    {
                        sc = Message[i];
                        i++;
                    }
                    paddedStr += fc;
                    paddedStr += sc;
                }
            }
            return paddedStr;
        }
    }
}
之后想的是再用2个方法完成任务。一个是GetMatrix方法把一开始处理好的KEY做成5*5的矩阵,一个是EncryptStr方法,把处理好的明文对照KEY做成密码输出。看到过别人的一个方法非常巧妙,但不知如何实现:先取得传入原文字符串长度,使用For循环字符串长度除以2次,每次把字符串的第i次和第i+1次分别赋给两个临时Char变量。之后用string类的indexof方法取得这两个字母在Key序列中的位置。由于5*5矩阵,那么所在位置除以5就是他的行号,除以5的余数就是他的列号,继续判断,如果是在同行,那么如果有一个除以5的余数为0,那么说明这个字母在行末。则取该行第一个值,否则取所在位置加一的值。继续来判断同列,如果所在位置大于19,那么必然是在矩阵最下面一层,那么位置减20就是他的密文。如果不是列末,那么位置加5就是他的密文。最后如果既不在同行又不在同列,那么他所在位置除以5后取整再乘以5就是他的行地址,再加上位置除以5的余数就是他的密文位置。

小弟才疏学浅,想破脑袋也束手无策。恳请各路高手帮帮我吧!非常非常的感谢!!
搜索更多相关主题的帖子: 澳大利亚 布尔战争 世界大战 密码 
2011-04-21 00:13
qq1023569223
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:湖南科技大学
等 级:贵宾
威 望:26
帖 子:2753
专家分:13404
注 册:2010-12-22
得分:0 
等有时间了,想想!

   唯实惟新 至诚致志
2011-04-21 06:41
athenalux
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:河北石家庄
等 级:小飞侠
威 望:8
帖 子:975
专家分:2514
注 册:2008-11-26
得分:0 
看起来挺麻烦的

QQ:81704464
2011-04-21 07:30
lwsfyts
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:39
专家分:132
注 册:2011-4-3
得分:0 
你的处理密钥KEY的方法好像只是处理了非字母的
2011-04-21 07:36
lwsfyts
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:39
专家分:132
注 册:2011-4-3
得分:20 
处理密钥KEY的方法:
private static string GetKey(string key)
        {
            string Firststep=key.ToUpper();//大写           
            //去掉非字母的
            Firststep = Regex.Replace(Firststep, "[^A-Z]+", "");
            Firststep += "ABCDEFGHIJKLMNOPRSTUVWXYZ";//去掉Q
            //去掉重复的字母
            string keyWord = string.Empty; ;
            foreach (char ch in Firststep)
            {
                if (!keyWord.Contains(ch))
                {
                    keyWord += ch;
                }
            }
            return keyWord;
        }  
2011-04-21 08:43
lwsfyts
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:39
专家分:132
注 册:2011-4-3
得分:0 
明文处理方法:
private static string SetMessage(string message)
        {            
            string Firststep = message.ToUpper();
            Firststep = Regex.Replace(Firststep, "[^A-Z]+", "");
            //相同字母+X
            for (int i = 0; i < Firststep.Length - 1; i++)
            {
                if (Firststep[i] == Firststep[i + 1])
                {
                    Firststep = Firststep.Insert(i + 1, "X");
                    i++;
                }
            }
            //余下一个字母+X
            if (Firststep.Length % 2 != 0)
            {
                Firststep += "X";
            }
            for (int i = 2; i < Firststep.Length; i++)
            {
                Firststep = Firststep.Insert(i, " ");
                i += 2;
            }
            return Firststep;
        }
2011-04-21 08:52
lwsfyts
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:39
专家分:132
注 册:2011-4-3
得分:0 
得到密文的方法:
private static string SetPassword(string keyWord, string setMes)
        {           
            string[] mes = setMes.Split(' ');
            string password = String.Empty;
            for (int i = 0; i < mes.Length; i++)
            {
                int x = keyWord.IndexOf(mes[i][0]);//第一个字母的位置
                int y = keyWord.IndexOf(mes[i][1]);//第二个字母的位置
                int index = Math.Abs(x - y);
                int xl=0;//密码的第一个字母
                int yl=0;//密码的第二个字母;
                //同行
                if (x/5==y/5)
                {                    
                    if (x % 5 == 4)
                    {
                        xl = x - 4;
                    }
                    else
                    {
                        xl = x + 1;
                    }
                    if (y % 5 == 4)
                    {
                        yl = y - 4;
                    }
                    else
                    {
                        yl = y + 1;
                    }

                }
                //同列
                else if (index % 5 == 0)
                {
                    if (x > 19)
                    {
                        xl = x % 5;
                    }
                    else
                    {
                        xl = x + 5;
                    }
                    if (y > 19)
                    {
                        yl = y % 5;
                    }
                    else
                    {
                        yl = y + 5;
                    }
                }
                else
                {
                    
                    xl = x - (x % 5 - y % 5);
                    yl = y + (x % 5 - y % 5);
                  
                }
                password += keyWord[xl] + "" + keyWord[yl];

            }
            for (int i = 2; i < password.Length; i++)
            {
                password = password.Insert(i, " ");
                i += 2;
            }
            return password;
        }
2011-04-21 10:22
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
先看看再说 LZ的帖子不错 支持

出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2011-04-21 18:45
GLaDOS
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2011-4-20
得分:0 
谢谢各路大大的关注!特别感谢6、7L!进度前进了一点了!

PS:这道题目其实还有其他2个任务:1.制作一个词组计数表,导入一篇很长的文章,扫描每2个字组成的词组,计数其出现的次数,最后把结果保存在一个文件中(.DIG)
2.解密!自己产生一个密钥,然后不断修改自己的密钥一直到其解密的文档尽可能的正确。完全没有头绪的东西。。。。
写在这里,有心人看看就是了。
2011-04-22 09:57



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-337392-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.095405 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved