崩坏学园英文名字首字母大写字母怎么弄大写

资料图鉴:教程速查:
当前位置:
我的世界大写字母H头颅指令
小编:3F时间: 16:37
  大写字母H
  /give @p skull 1 3 {display:{Name:&H&},SkullOwner:{Id:&ba7a5f3c-db71--ce6bd82ee992&,Properties:{textures:[{Value:&eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzFmMzQ2MmE0NzM1NDlmMTQ2OWY4OTdmODRhOGQ0MTE5YmM3MWQ0YTVkODUyZTg1YzI2YjU4OGE1YzBjNzJmIn19fQ==&}]}}}
  备注:双击代码即可全选
  头颅指令使用方法:
  1、获取命令方块
  游戏中调整为创造模式后,在输入框中输入/give id command_block 1即可获得命令方块;备注:ID即为玩家游戏名字
  2、复制指令并输入
  复制指令后将指令粘贴进命令方块中
  3、执行命令方块即可获得对应的头颅
  游戏园我的世界官方群: 或 &欢迎各路喜爱我的世界的小伙伴们加入讨论!
  玩服务器的小伙伴们可以加入:&群一起联机玩游戏哦!
  如果你是腐竹的话可以给我们投稿你的服务器哦~投稿地址:
  如果你有心仪的作品或者心得分享的话,欢迎来游戏园投稿,大家可以点击&&&&&&进行投稿哦~&有奖品哦~
我的世界头颅大全_我的世界头颅指令代码
分享到:更多
类型:休闲娱乐平台:PC,iOS,安卓
游戏大礼包手游开测表
剑与家园光棍节脱单礼包烈焰龙城激活码魔法王座大电影上线礼包古剑绝学撩妹礼包剑与家园狂欢节装扮礼包光明大陆万圣节糖果礼包
11-03公测11-02内测10-31内测10-26内测10-26公测10-2410-19内测09-29公测09-2809-27公测
攻略推荐本月最新
手游排行网游单机资料图鉴:教程速查:
当前位置:
我的世界大写字母D头颅指令
小编:3F时间: 16:37
  大写字母D
  /give @p skull 1 3 {display:{Name:&D&},SkullOwner:{Id:&c142dbd3-dbdf-4f46-a491-e8e&,Properties:{textures:[{Value:&eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzE5M2RjMGQ0YzVlODBmZjlhOGEwNWQyZmNmZTI2OTUzOWNiMzkyNzE5MGJhYzE5ZGEyZmNlNjFkNzEifX19&}]}}}
  备注:双击代码即可全选
  头颅指令使用方法:
  1、获取命令方块
  游戏中调整为创造模式后,在输入框中输入/give id command_block 1即可获得命令方块;备注:ID即为玩家游戏名字
  2、复制指令并输入
  复制指令后将指令粘贴进命令方块中
  3、执行命令方块即可获得对应的头颅
  游戏园官方群: 或 &欢迎各路喜爱我的世界的小伙伴们加入讨论!
  玩服务器的小伙伴们可以加入:&群一起联机玩游戏哦!
  如果你是腐竹的话可以给我们投稿你的服务器哦~投稿地址:
  如果你有心仪的作品或者心得分享的话,欢迎来游戏园投稿,大家可以点击&&&&&&进行投稿哦~&有奖品哦~
我的世界头颅大全_我的世界头颅指令代码
分享到:更多
类型:休闲娱乐平台:PC,iOS,安卓
游戏大礼包手游开测表
剑与家园光棍节脱单礼包烈焰龙城激活码魔法王座大电影上线礼包古剑绝学撩妹礼包剑与家园狂欢节装扮礼包光明大陆万圣节糖果礼包
11-03公测11-02内测10-31内测10-26内测10-26公测10-2410-19内测09-29公测09-2809-27公测
攻略推荐本月最新
手游排行网游单机动态规划的本质不在于是递推或是递归,也不需要纠结是不是内存换时间。&br&&br&理解动态规划并不需要数学公式介入,只是完全解释清楚需要点篇幅…首先需要明白哪些问题不是动态规划可以解决的,才能明白为神马需要动态规划。不过好处时顺便也就搞明白了递推贪心搜索和动规之间有什么关系,以及帮助那些总是把动规当成搜索解的同学建立动规的思路。当然熟悉了之后可以直接根据问题的描述得到思路,如果有需要的话再补充吧。&br&&br&动态规划是对于 某一类问题 的解决方法!!重点在于如何鉴定“某一类问题”是动态规划可解的而不是纠结解决方法是递归还是递推!&br&&br&怎么鉴定dp可解的一类问题需要从计算机是怎么工作的说起…计算机的本质是一个状态机,内存里存储的所有数据构成了当前的状态,CPU只能利用当前的状态计算出下一个状态(不要纠结硬盘之类的外部存储,就算考虑他们也只是扩大了状态的存储容量而已,并不能改变下一个状态只能从当前状态计算出来这一条铁律)&br&&br&&br&当你企图使用计算机解决一个问题是,其实就是在思考如何将这个问题表达成状态(用哪些变量存储哪些数据)以及如何在状态中转移(怎样根据一些变量计算出另一些变量)。所以所谓的空间复杂度就是为了支持你的计算所必需存储的状态最多有多少,所谓时间复杂度就是从初始状态到达最终状态中间需要多少步!&br&&br&太抽象了还是举个例子吧:&br&&br&比如说我想计算第100个非波那契数,每一个非波那契数就是这个问题的一个状态,每求一个新数字只需要之前的两个状态。所以同一个时刻,最多只需要保存两个状态,空间复杂度就是常数;每计算一个新状态所需要的时间也是常数且状态是线性递增的,所以时间复杂度也是线性的。&br&&br&上面这种状态计算很直接,只需要依照固定的模式从旧状态计算出新状态就行(a[i]=a[i-1]+a[i-2]),不需要考虑是不是需要更多的状态,也不需要选择哪些旧状态来计算新状态。对于这样的解法,我们叫递推。&br&&br&非波那契那个例子过于简单,以至于让人忽视了阶段的概念,所谓阶段是指随着问题的解决,在同一个时刻可能会得到的不同状态的集合。非波那契数列中,每一步会计算得到一个新数字,所以每个阶段只有一个状态。想象另外一个问题情景,假如把你放在一个围棋棋盘上的某一点,你每一步只能走一格,因为你可以东南西北随便走,所以你当你同样走四步可能会处于很多个不同的位置。从头开始走了几步就是第几个阶段,走了n步可能处于的位置称为一个状态,走了这n步所有可能到达的位置的集合就是这个阶段下所有可能的状态。&br&&br&现在问题来了,有了阶段之后,计算新状态可能会遇到各种奇葩的情况,针对不同的情况,就需要不同的算法,下面就分情况来说明一下:&br&&br&&br&假如问题有n个阶段,每个阶段都有多个状态,不同阶段的状态数不必相同,一个阶段的一个状态可以得到下个阶段的所有状态中的几个。那我们要计算出最终阶段的状态数自然要经历之前每个阶段的某些状态。&br&&br&好消息是,有时候我们并不需要真的计算所有状态,比如这样一个弱智的棋盘问题:从棋盘的左上角到达右下角最短需要几步。答案很显然,用这样一个弱智的问题是为了帮助我们理解阶段和状态。某个阶段确实可以有多个状态,正如这个问题中走n步可以走到很多位置一样。但是同样n步中,有哪些位置可以让我们在第n+1步中走的最远呢?没错,正是第n步中走的最远的位置。换成一句熟悉话叫做“下一步最优是从当前最优得到的”。所以为了计算最终的最优值,只需要存储每一步的最优值即可,解决符合这种性质的问题的算法就叫贪心。如果只看最优状态之间的计算过程是不是和非波那契数列的计算很像?所以计算的方法是递推。&br&&br&既然问题都是可以划分成阶段和状态的。这样一来我们一下子解决了一大类问题:一个阶段的最优可以由前一个阶段的最优得到。&br&&br&如果一个阶段的最优无法用前一个阶段的最优得到呢?&br&&br&什么你说只需要之前两个阶段就可以得到当前最优?那跟只用之前一个阶段并没有本质区别。最麻烦的情况在于你需要之前所有的情况才行。&br&&br&再来一个迷宫的例子。在计算从起点到终点的最短路线时,你不能只保存当前阶段的状态,因为题目要求你最短,所以你必须知道之前走过的所有位置。因为即便你当前再的位置不变,之前的路线不同会影响你的之后走的路线。这时你需要保存的是之前每个阶段所经历的那个状态,根据这些信息才能计算出下一个状态!&br&&br&每个阶段的状态或许不多,但是每个状态都可以转移到下一阶段的多个状态,所以解的复杂度就是指数的,因此时间复杂度也是指数的。哦哦,刚刚提到的之前的路线会影响到下一步的选择,这个令人不开心的情况就叫做有后效性。&br&&br&刚刚的情况实在太普遍,解决方法实在太暴力,有没有哪些情况可以避免如此的暴力呢?&br&&br&契机就在于后效性。&br&&br&有一类问题,看似需要之前所有的状态,其实不用。不妨也是拿最长上升子序列的例子来说明为什么他不必需要暴力搜索,进而引出动态规划的思路。&br&&br&假装我们年幼无知想用搜索去寻找最长上升子序列。怎么搜索呢?需要从头到尾依次枚举是否选择当前的数字,每选定一个数字就要去看看是不是满足“上升”的性质,这里第i个阶段就是去思考是否要选择第i个数,第i个阶段有两个状态,分别是选和不选。哈哈,依稀出现了刚刚迷宫找路的影子!咦慢着,每次当我决定要选择当前数字的时候,只需要和之前选定的一个数字比较就行了!这是和之前迷宫问题的本质不同!这就可以纵容我们不需要记录之前所有的状态啊!既然我们的选择已经不受之前状态的组合的影响了,那时间复杂度自然也不是指数的了啊!虽然我们不在乎某序列之前都是什么元素,但我们还是需要这个序列的长度的。所以我们只需要记录以某个元素结尾的LIS长度就好!因此第i个阶段的最优解只是由前i-1个阶段的最优解得到的,然后就得到了DP方程(感谢 &a data-hash=&5fed4a0fa7df5f9a8e24c40& href=&///people/5fed4a0fa7df5f9a8e24c40& class=&member_mention& data-tip=&p$b$5fed4a0fa7df5f9a8e24c40& data-hovercard=&p$b$5fed4a0fa7df5f9a8e24c40&&@韩曦&/a& 指正)&br&&img src=&///equation?tex=LIS%28i%29%3Dmax%5C%7BLIS%28j%29%2B1%5C%7D+%0A%5C+%5C+%5C+%5C+%0Aj%3Ci+%5C+and%5C+a%5Bj%5D+%3C+a%5Bi%5D& alt=&LIS(i)=max\{LIS(j)+1\}
j&i \ and\ a[j] & a[i]& eeimg=&1&&&br&&br&所以一个问题是该用递推、贪心、搜索还是动态规划,完全是由这个问题本身阶段间状态的转移方式决定的!&br&&br&每个阶段只有一个状态-&递推;&br&每个阶段的最优状态都是由上一个阶段的最优状态得到的-&贪心;&br&每个阶段的最优状态是由之前所有阶段的状态的组合得到的-&搜索;&br&每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到而不管之前这个状态是如何得到的-&动态规划。&br&&br&&blockquote&每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到&/blockquote&这个性质叫做最优子结构;&br&&br&&blockquote&而不管之前这个状态是如何得到的&br&&/blockquote&这个性质叫做无后效性。&br&&br&另:其实动态规划中的最优状态的说法容易产生误导,以为只需要计算最优状态就好,LIS问题确实如此,转移时只用到了每个阶段“选”的状态。但实际上有的问题往往需要对每个阶段的所有状态都算出一个最优值,然后根据这些最优值再来找最优状态。比如背包问题就需要对前i个包(阶段)容量为j时(状态)计算出最大价值。然后在最后一个阶段中的所有状态种找到最优值。
动态规划的本质不在于是递推或是递归,也不需要纠结是不是内存换时间。 理解动态规划并不需要数学公式介入,只是完全解释清楚需要点篇幅…首先需要明白哪些问题不是动态规划可以解决的,才能明白为神马需要动态规划。不过好处时顺便也就搞明白了递推贪心搜…
&b&动态规划中递推式的求解方法不是动态规划的本质。&/b&&br&&br&我曾经作为省队成员参加过NOI,保送之后也给学校参加NOIP的同学多次讲过动态规划,我试着讲一下我理解的&b&动态规划&/b&,争取深入浅出。希望你看了我的答案,能够喜欢上动态规划。&br&&br&0. 动态规划的本质,是对问题&b&&i&状态的定义&/i&&/b&和&b&&i&状态转移方程&/i&的定义&/b&。&br&引自维基百科&br&&blockquote&&b&dynamic programming&/b& is a method for solving a complex problem by &b&breaking it down into a collection of simpler subproblems&/b&.&/blockquote&动态规划是通过&b&拆分问题,&/b&定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。&br&本题下的其他答案,大多都是在说递推的求解方法,但&b&如何拆分问题&/b&,才是动态规划的核心。&br&而&b&拆分问题&/b&,靠的就是&b&&i&状态的定义&/i&&/b&和&b&&i&状态转移方程&/i&的定义&/b&。&br&&br&1. 什么是&b&状态的定义?&/b&&br&&b&&br&首先想说大家千万不要被下面的数学式吓到,这里只涉及到了函数相关的知识。&/b&&br&我们先来看一个动态规划的教学必备题:&br&&blockquote&给定一个数列,长度为N,&br&求这个数列的最长上升(递增)子数列(LIS)的长度.&br&以&br&1 7 2 8 3 4&br&为例。&br&这个数列的最长递增子数列是 1 2 3 4,长度为4;&br&次长的长度为3, 包括 1 7 8; 1 2 3 等.&/blockquote&要解决这个问题,我们首先要&b&定义这个问题&/b&和这个问题的子问题。&br&有人可能会问了,题目都已经在这了,我们还需定义这个问题吗?需要,原因就是这个问题在字面上看,找不出子问题,而没有子问题,这个题目就没办法解决。&br&&br&所以我们来重新定义这个问题:&br&&blockquote&给定一个数列,长度为N,&br&设&img src=&///equation?tex=F_%7Bk%7D& alt=&F_{k}& eeimg=&1&&为:以数列中第k项结尾的最长递增子序列的长度.&br&求&img src=&///equation?tex=F_%7B1%7D..F_%7BN%7D& alt=&F_{1}..F_{N}& eeimg=&1&& 中的最大值.&/blockquote&显然,这个新问题与原问题等价。&br&而对于&img src=&///equation?tex=F_%7Bk%7D& alt=&F_{k}& eeimg=&1&&来讲,&img src=&///equation?tex=F_%7B1%7D+..+F_%7Bk-1%7D& alt=&F_{1} .. F_{k-1}& eeimg=&1&&都是&img src=&///equation?tex=F_%7Bk%7D& alt=&F_{k}& eeimg=&1&&的子问题:因为以第k项结尾的最长递增子序列(下称LIS),包含着以第&img src=&///equation?tex=1..k-1& alt=&1..k-1& eeimg=&1&&中某项结尾的LIS。&br&&br&上述的新问题&img src=&///equation?tex=F_%7Bk%7D& alt=&F_{k}& eeimg=&1&&也可以叫做状态,定义中的“&img src=&///equation?tex=F_%7Bk%7D& alt=&F_{k}& eeimg=&1&&为数列中第k项结尾的LIS的长度”,就叫做对状态的定义。&br&之所以把&img src=&///equation?tex=F_%7Bk%7D& alt=&F_{k}& eeimg=&1&&做“状态”而不是“问题” ,一是因为避免跟原问题中“问题”混淆,二是因为这个新问题是数学化定义的。&br&&br&&br&对状态的定义只有一种吗?&i&当然不是&/i&。&br&我们甚至可以二维的,以完全不同的视角定义这个问题:&br&&blockquote&给定一个数列,长度为N,&br&设&img src=&///equation?tex=F_%7Bi%2C+k%7D& alt=&F_{i, k}& eeimg=&1&&为:&br&在前i项中的,长度为k的最长递增子序列中,最后一位的最小值. &img src=&///equation?tex=1%5Cleq+k%5Cleq+N& alt=&1\leq k\leq N& eeimg=&1&&.&br&若在前i项中,不存在长度为k的最长递增子序列,则&img src=&///equation?tex=F_%7Bi%2C+k%7D& alt=&F_{i, k}& eeimg=&1&&为正无穷.&br&求最大的x,使得&img src=&///equation?tex=F_%7BN%2Cx%7D& alt=&F_{N,x}& eeimg=&1&&不为正无穷。&/blockquote&这个新定义与原问题的等价性也不难证明,请读者体会一下。&br&上述的&img src=&///equation?tex=F_%7Bi%2C+k%7D& alt=&F_{i, k}& eeimg=&1&&就是状态,定义中的“&img src=&///equation?tex=F_%7Bi%2C+k%7D& alt=&F_{i, k}& eeimg=&1&&为:在前i项中,长度为k的最长递增子序列中,最后一位的最小值”就是对状态的定义。&br&&br&&br&2. 什么是&b&状态转移方程&/b&?&br&上述状态定义好之后,状态和状态之间的关系式,就叫做&b&状态转移方程。&/b&&br&&br&比如,对于LIS问题,我们的第一种定义:&br&&blockquote&设&img src=&///equation?tex=F_%7Bk%7D& alt=&F_{k}& eeimg=&1&&为:以数列中第k项结尾的最长递增子序列的长度.&/blockquote&设A为题中数列,状态转移方程为:&br&&blockquote&&img src=&///equation?tex=F_%7B1%7D+%3D+1& alt=&F_{1} = 1& eeimg=&1&& (根据状态定义导出边界情况)&br&&img src=&///equation?tex=F_%7Bk%7D%3Dmax%28F_%7Bi%7D%2B1+%7C+A_%7Bk%7D%3EA_%7Bi%7D%2C+i%5Cin+%281..k-1%29%29+& alt=&F_{k}=max(F_{i}+1 | A_{k}&A_{i}, i\in (1..k-1)) & eeimg=&1&&&img src=&///equation?tex=%28k%3E1%29& alt=&(k&1)& eeimg=&1&&&/blockquote&用文字解释一下是:&br&以第k项结尾的LIS的长度是:保证第i项比第k项小的情况下,以第i项结尾的LIS长度加一的最大值,取遍i的所有值(i小于k)。&br&&br&第二种定义:&br&&blockquote&设&img src=&///equation?tex=F_%7Bi%2C+k%7D& alt=&F_{i, k}& eeimg=&1&&为:在数列前i项中,长度为k的递增子序列中,最后一位的最小值&/blockquote&设A为题中数列,状态转移方程为:&br&&blockquote&若&img src=&///equation?tex=A_%7Bi%7D%3EF_%7Bi-1%2Ck-1%7D& alt=&A_{i}&F_{i-1,k-1}& eeimg=&1&&则&img src=&///equation?tex=F_%7Bi%2Ck%7D%3Dmin%28A_%7Bi%7D%2CF_%7Bi-1%2Ck%7D%29+& alt=&F_{i,k}=min(A_{i},F_{i-1,k}) & eeimg=&1&&&br&否则:&img src=&///equation?tex=F_%7Bi%2Ck%7D%3DF_%7Bi-1%2Ck%7D+& alt=&F_{i,k}=F_{i-1,k} & eeimg=&1&&&/blockquote&(边界情况需要分类讨论较多,在此不列出,需要根据状态定义导出边界情况。)&br&大家套着定义读一下公式就可以了,应该不难理解,就是有点绕。&br&&br&这里可以看出,这里的状态转移方程,就是定义了问题和子问题之间的关系。&br&可以看出,状态转移方程就是带有条件的递推式。&br&&br&&b&3. 动态规划迷思&/b&&br&本题下其他用户的回答跟动态规划都有或多或少的联系,我也讲一下与本答案的联系。&br&&br&a. “缓存”,“重叠子问题”,“记忆化”:&br&这三个名词,都是在阐述递推式求解的技巧。以Fibonacci数列为例,计算第100项的时候,需要计算&u&第99项&/u&和98项;在计算第101项的时候,需要第100项和&u&第99项&/u&,这时候你还需要重新计算第99项吗?不需要,你只需要在第一次计算的时候把它记下来就可以了。&br&上述的需要再次计算的“第99项”,就叫“重叠子问题”。如果没有计算过,就按照递推式计算,如果计算过,直接使用,就像“缓存”一样,这种方法,叫做“记忆化”,这是递推式求解的技巧。这种技巧,通俗的说叫“花费空间来节省时间”。&b&都不是动态规划的本质,&/b&&b&不是动态规划的核心。&/b&&br&&br&b. “递归”:&br&递归是递推式求解的方法,连技巧都算不上。&br&&br&c. &无后效性&,“最优子结构”:&br&上述的状态转移方程中,等式右边不会用到下标大于左边i或者k的值,这是&无后效性&的通俗上的数学定义,符合这种定义的状态定义,我们可以说它具有“最优子结构”的性质,在动态规划中我们要做的,就是找到这种“最优子结构”。&br&&b&在对状态和状态转移方程的定义过程中,满足“最优子结构”是一个隐含的条件(否则根本定义不出来)。对状态和“最优子结构”的关系的进一步解释,&a href=&/question//answer/& class=&internal&&什么是动态规划?动态规划的意义是什么? - 王勐的回答&/a& 写的很好,大家可以去读一下。&/b&&br&&br&需要注意的是,一个问题可能有多种不同的状态定义和状态转移方程定义,存在一个有后效性的定义,&i&&b&不代表该问题不适用动态规划&/b&&/i&。这也是其他几个答案中出现的逻辑误区:&br&动态规划方法要寻找符合“最优子结构“的状态和状态转移方程的定义&b&,&/b&在找到之后,这个问题就可以以“记忆化地求解递推式”的方法来解决。而寻找到的定义,才是动态规划的本质。&br&&br&&b&有位答主说:&/b&&br&&blockquote&分治在求解每个子问题的时候,都要进行一遍计算&br&动态规划则存储了子问题的结果,查表时间为常数&/blockquote&这就像说多加辣椒的菜就叫川菜,多加酱油的菜就叫鲁菜一样,是存在误解的。&br&&br&文艺的说,动态规划是寻找一种对问题的观察角度,让问题能够以递推(或者说分治)的方式去解决。寻找看问题的角度,才是动态规划中最耀眼的宝石!(大雾)
动态规划中递推式的求解方法不是动态规划的本质。 我曾经作为省队成员参加过NOI,保送之后也给学校参加NOIP的同学多次讲过动态规划,我试着讲一下我理解的动态规划,争取深入浅出。希望你看了我的答案,能够喜欢上动态规划。 0. 动态规划的本质,是对问题状…
我刚刚在博客上写了一篇和楼主问题相关的文章,楼主可以参考一下:&br&&p&快大学毕业了,突然发现整个大学生涯就是吃喝睡,玩游戏,上课,难道我以后的回忆就剩下这些东西吗?所以我下定决心开始干我一直想干却因为拖延症一直没干的事,开个属于自己的独立博客便是其中之一。&/p&&p&SO,just do it! 我上各种网站去查找建站方法,但悲催的是我是一个文科生,难一点的,涉及到代码的东西我看了就发蒙。不过,幸好,我上知乎的时候,发现我有人和我一样的烦恼,而回答的人都叫他用wordpress,这个号称5秒钟建站的神器。&/p&&p&我到wordpress官网:&a href=&///?target=http%3A//cn.wordpress.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&China 简体中文&i class=&icon-external&&&/i&&/a&下载了这个软件,但是我当时没有网站,要怎么使用呢,于是我百度到了一个可以把我的电脑变成服务器,让网页本地运行的东西-----XAMPP。&/p&&p&具体怎么样运用,大家可以看这篇百度经验:用XAMPP来搭建Wordpress建站环境&/p&&p&&a href=&///?target=http%3A///article/f71d6ab641d117.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/artic&/span&&span class=&invisible&&le/f71d6ab641d117.html&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&/p&&p&xampp下载:&a href=&///?target=http%3A///soft/61448.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&xampps下载1.9.5 最新版 X64_xampp优化版php集成包西西软件下载&i class=&icon-external&&&/i&&/a&&/p&&p&弄好了,我就开始下各种主题和插件,一直折腾到我觉得满意后,我决定开始玩真的,建站!&/p&1.买域名&p&本来我的选择只有万网或者新网,但是后来听说国内的域名注册一点都不自由,说封就封,而且基本上没有转让域名的可能性。所以我果断出国啦,网友推荐我用狗爹godaddy,我去看了一下价格觉得还不错,而且目前已中文化,&/p&&p&&strong&点击进入:&a href=&///?target=https%3A///zh%3Fisc%3Dgennbacn29%26countryview%3D1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&狗爹中文官网&i class=&icon-external&&&/i&&/a&&/strong&&/p&&p&另外建议百度一下优惠码再购买,可以省一些钱。&/p&2.买空间&p&我本来想买阿里云空间的,但是看了看价格,还是算了。所以就想买个最便宜的美国虚拟主机,由于英语不行,去外国网站买虚拟空间后台管理肯定生不如死,所以我就找在中国有代理美国空间的空间商,知乎上都推荐老鹰主机,或者老薛主机,我对比了一下,还是老薛主机便宜,于是就买了最便宜的50元美国空间,付款的时候问了客服有没有优惠码,最后一共花了35元。&/p&&p&&strong&点击进入:&a href=&///?target=https%3A//my.laoxuehost.net/aff.php%3Faff%3D2252& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&老薛主机&i class=&icon-external&&&/i&&/a&&/strong&&/p&3.安装wordpress&p&老薛主机的后台是cPane的,我完全没见过,于是参考了这篇教程,&/p&&p&cPanel安装WordPress中文教程&a href=&///?target=http%3A////cpanel-wordpress-china/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&cPanel安装WordPress中文教程&i class=&icon-external&&&/i&&/a&&/p&&p&但是在网页上直接上传实在太慢,我采用FlashFXP工具上传,不过要先去cPanel-ftp账户那里设置一下账号密码,IP就是空间的共享IP。&/p&4.域名绑定空间&p&这个我不知道啥原理,但是DNSPOD上面有教程:&/p&点击查看:&a href=&///?target=https%3A///Kb/showarticle/tsid/42/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Godaddy注册商域名修改DNS地址&i class=&icon-external&&&/i&&/a&&p&要注意的是A记录要设置俩个,一个是www,一个是@。这样www开头的域名才能打开。&/p&&p&大概就是这样了,欢迎转载,但是请注明转载自我的博客哦!&/p&&p&好好琢磨:&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&好好琢磨 | 若有所思,若有所得,与你共享,与有荣焉&i class=&icon-external&&&/i&&/a&&/p&
我刚刚在博客上写了一篇和楼主问题相关的文章,楼主可以参考一下: 快大学毕业了,突然发现整个大学生涯就是吃喝睡,玩游戏,上课,难道我以后的回忆就剩下这些东西吗?所以我下定决心开始干我一直想干却因为拖延症一直没干的事,开个属于自己的独立博客便…
首先声明一下,答主没有看过《模仿游戏》这部电影,不知道这部影片中有多少演绎的成分,所以只是根据史实讲述一下二战中德军的恩格玛机(Enigma machine)是如何被破解的。&br&&br&好,我们开始。&br&&br&想要理解恩格玛机是如何被破解的,首先要理解这种机器的加密原理。虽然恩格玛机看起来复杂,但它进行加密的基本原理并不复杂。这种机器所做的本质上是一种&b&替换加密&/b&(Substitution Cipher)。&br&&br&不要被这个名字吓倒,我们首先来看一下替换加密是什么东西。&br&&br&&b&1)替换加密的原理及破解方法&/b&&br&&br&&br&在古代,当人们想要对一段文字进行加密时,会把原文(即明文)中的字母按照某种配对关系替换成其他的字母,从而得到一段别人看不懂的密文。&br&&br&例如我们可以按照以下的配对关系对明文进行加密:&br&&br&&figure&&img src=&/40d69bb8ebd39d3fd3b907f0f73992f0_b.jpg& data-rawwidth=&7504& data-rawheight=&792& class=&origin_image zh-lightbox-thumb& width=&7504& data-original=&/40d69bb8ebd39d3fd3b907f0f73992f0_r.jpg&&&/figure&&br&在加密过程中,第一行明码表中的字母分别被替换成位于该字母下方的大写字母。加密结束后,将会得到一段不经解密谁也看不懂的密文。&br&&br&比方说我们现在要对下面这段明文进行加密:&br&&br&when you are old and grey and full of sleep&br&&br&按照上面的替换规则加密后,我们将得到一段密文:&br&&br&KRUZ NAI CFU AXP CZP EFUN CZP TIXX AT GXUUB&br&&br&就这样,我们完成了一次替换加密。我们得到的这段密文被破解的难度有多大呢?理论上讲,破解者可以用各种可能的密码表组合来试着解密这段话。但由于26个字母可能的排列顺序有4.03X10^26种之多,这意味着如果全世界60亿人每人每秒可以测试一种可能的密码表,也需要21亿年才能试完所有的排列组合。事实上,在很长的一段时间里,这种简单的替换密码被认为是无法被破解的。&br&&br&按理说,我们的故事到这里就应该结束了。靠着这种无法被破解的密码,密码的发送者和接收者像童话里的王子和公主一样,从此过上了永远幸福的生活。&br&&br&但是,在这个世界上,偏偏就是有人能想出巧妙的方法来破解这种看似无懈可击的密码。他们所使用的武器是语言学和统计学。&br&&br&在使用字母文字的语言中,每一个字母在普通的文本中出现的概率事实上是不同的。以英语为例,在一篇普通的文章中,字母e, a, t出现的概率远远大于j, x, z出现的概率。如果对足够多的文本进行分析,我们就可以统计出每一个字母在英语文本中出现的平均概率。&br&&br&下面这张图片来自维基百科,显示的是26个字母在普通的英文文本中出现的概率:&br&&br&&figure&&img src=&/0ecfeb675f7b06cc6f9ce94_b.jpg& data-rawwidth=&600& data-rawheight=&480& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&/0ecfeb675f7b06cc6f9ce94_r.jpg&&&/figure&&br&我们刚刚进行的替换加密中,虽然每一个字母都改头换面变成了另一个字母,但这并不能改变它在一段文本中出现的频率。例如在刚刚的加密过程中,字母e被替换成了U,如果我们截取足够长的密文进行分析的话,我们会发现在密文中字母U出现的频率要远远高于其他字母。只要对照上面这张概率图,把密文中出现频率最高的几个字母依次试着替换为e, t, a这几个高频字母,就可以对密文进行破解。&br&&br&作为辅助手段,我们还可以统计密文中每个字母左右两边的字母出现频率。如果一个字母可以出现在大多数字母的两旁,那么它很有可能是一个元音字母。反之,如果一个字母永远也不会出现在某些特定字母的旁边,那么它很可能是一个辅音字母,因为在英语中一些辅音字母是永远不会被拼写在一起的。&br&&br&至此,我们上面介绍的这种&b&单字母替换密码&/b&被无情地破解了。&br&&br&于是,不死心的密码师们又发明了&b&多字母替换密码&/b&。&br&&br&下面的内容开始逐渐进入烧脑状态,建议大家在头脑清醒的时候阅读。&br&&br&单字母替换密码的一个致命缺陷是明文中的每一个字母都被唯一地替换为了密文中的另一个字母,这种一对一的替换关系是恒定不变的。破解者正是抓住这一漏洞,对截获的密文进行字母频率分析,找到这种一对一的替换关系,最终打败了密码师。&br&&br&在这个时候,顽强的密码师们说,谁规定在加密中只能使用一行密码表了?如果同时使用两行密码表会怎么样呢?让我们来看一下:&br&&figure&&img src=&/95de7cf51dcba37d8a36c0_b.jpg& data-rawwidth=&7528& data-rawheight=&1008& class=&origin_image zh-lightbox-thumb& width=&7528& data-original=&/95de7cf51dcba37d8a36c0_r.jpg&&&/figure&&br&与刚刚的单字母替换加密相比,我们又增加了一行密码表。有了这两行密码表,我们就可以在加密过程中对明文中的第一个字母使用密码表1进行加密,对第二个字母使用密码表2进行加密,第三个字母又重新使用密码表1,第四个字母使用密码表2,如此重复一直到对整段明文进行加密。&br&&br&大家可以试着用这种&b&多字母替换密码&/b&加密一下刚刚的那一段明文:&br&&br&when you are old and grey and full of sleep&br&&br&注意到什么特别之处了吗?&br&&br&如果使用多字母替换加密,这段话中的第三个字母e将会被替换为U,而第十个字母同样是e,却会被替换为L。这是因为由于所处的位置不同,这两个字母e分别是用密码表1和密码表2进行加密的,所以出现了两个不同的结果。&br&&br&也就是说,&b&多字母替换密码不但可以替换掉明文中的字母,同时还可以掩盖明文中字母出现的真实频率&/b&,从而使破解者使用的字母频率分析法立刻失效。&br&&br&密码师们笑得嘴都合不上了,他们继续问自己,既然可以使用两行密码表,那为什么不可以使用三行或者四行呢?不,让我们干脆弄一个二十五行的吧:&br&&br&&figure&&img src=&/690b13c871c2ca8c71c9747f5fba8eb4_b.jpg& data-rawwidth=&640& data-rawheight=&640& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/690b13c871c2ca8c71c9747f5fba8eb4_r.jpg&&&/figure&&br&上面这张表叫做维热纳尔方阵(Vigenère square),是为了方便加密者进行多字母替换而设计的。人们可以在表中选取任意行数的字母作为密码表进行加密,进一步提高了密码的复杂程度。&br&&br&有了多字母替换,密码发送者和接收者这次可以过上永远幸福的生活了吧?&br&&br&假设有一位勤劳的密码师,为了得到一份绝对安全的密码,他不辞劳苦地打算使用七行密码表对明文进行加密,为了方便记忆,他选取了GERMANY作为关键词。也就是说,密码师将分别使用位于上面方阵中G、E、R、M、A、N、Y行的字母作为密码表对明文中的字母进行循环加密。&br&&br&由于明文中的每一个字母都会被随机地替换为另外七个不同的字母,所以前面介绍过的频率分析法将不再起作用。这一次,密码师是不是终于得到了一份绝对安全的密文?&br&&br&答案当然是否定的。破解者很快就发明了新的破解方法。&br&&br&密码破译者在获得足够长的密文之后,可以寻找密文中重复出现的字母串。以英文为例,在一篇文章中有一些特定的单词例如the、and会反复出现。虽然在密文中这些单词有6/7的几率会被替换为不同的形式,但如果两个相同单词之间所间隔的字母数刚好是7的倍数的话,它们就会被替换为相同的形式。这是因为替换第二个单词时,总数为7行的密码表刚好完成了若干个完整的循环。&br&&br&只要截获足够长的密文,破解者就可以对重复出现的字母串之间的距离进行分析。&br&&br&假设破解者获得的分析结果是这样的:&br&&br&在相距21个字母的地方,重复出现了字母串GHI;&br&在相距77个字母的地方,重复出现了字母串TUIXS;&br&在相距147个字母的地方,重复出现了字母串OCD;&br&&br&……&br&&br&由于字母串重复出现的距离都是7的倍数,破解者可以由此确定,这份密文使用了7行密码表进行加密。如果各位都认真地阅读了前面介绍的单字母替换密码的破解方法,不用我说你们也知道下一步该怎么做了吧?&br&&br&破解者下一步只需要把密文中位于第1、8、15……位置的字母提取出来,写在一张纸上,组成第一个字母集合。这些字母全部是用第一行密码表进行加密的,虽然他现在还不知道这个密码表究竟是什么。&br&&br&然后再把密文中位于第2、9、16……位置的字母提取出来,组成第二个字母集合。&br&&br&……&br&&br&最后把密文中位于第7、14、21……位置的字母提取出来,组成第七个字母集合。&br&&br&接下来,破解者只要对这七个字母集合分别进行七次字母频率分析,就可以破解这份多字母替换密码。&br&&br&面对如此丧心病狂的破解者,无奈的密码师只能仰天长叹:“除非&b&每加密一个字母&/b&&b&就更换一次密码表并且永不重复&/b&,否则如论如何都逃不过被破解的命运。”&br&&br&“&b&每加密一个字母就更换一次密码表并且永不重复&/b&”理论上讲是可以做到的,只不过要加密一份有一万个字母的明文的话,就需要……呃,一个长达一万行的密码本。这样就产生了密码本比密文本身还要长的尴尬局面。&br&&br&就算有一位勤劳的密码师愿意花几个小时时间制作这样一份密文,密文的接收者也需要花同样长的时间将密文转化成明文,这种低效率的操作方式将大大限制密码的实用性。&br&&br&如果传送者和接收者之间存在大量的信息交换,那么制造和分发数量如此举得的密钥也将是不切实际的。在军队中,每天都有成千上万条信息在各地之间传递。如果为每一条信息中的每一个字母都创造一个随机密码表的话,可能每天都会消耗掉一个厚几百页的密钥本。如何制造出这么多的随机密钥,如何将这些密钥及时发送到全军各地,如何让全军中的操作员在发送和接收的时候都保持在密码本的同一位置,这些都会是难以解决的问题。(谢谢 &a data-hash=&ea092b01aa11d& href=&///people/ea092b01aa11d& class=&member_mention& data-editable=&true& data-title=&@申屠谦夏& data-tip=&p$b$ea092b01aa11d& data-hovercard=&p$b$ea092b01aa11d&&@申屠谦夏&/a& 指出了原文中的一个错误)&br&&br&综上所述,“每加密一个字母就更换一次密码表并且永不重复”的替换密码已经超出了人力所及的范围。&br&&br&不过,人类做不到的事情,不代表机器也无法做到。&br&&br&接下来,让我们来看一下恩格玛机的工作原理。&br&&br&&b&2)恩格玛机的工作原理&/b&&br&&br&先上一张图看一下恩格玛机是什么样的:&br&&br&&figure&&img src=&/b994b03240dcbff_b.jpg& data-rawwidth=&1414& data-rawheight=&1886& class=&origin_image zh-lightbox-thumb& width=&1414& data-original=&/b994b03240dcbff_r.jpg&&&/figure&&br&在上面这张图中,恩格玛机的四个主要部件被标示了出来,它们分别是:&br&&br&&b&键盘(Keyboard)&/b&:这个没什么好解释的,输入密码用的。&br&&b&灯盘(Lampboard)&/b&:在键盘上输入一个字母后,灯盘上会有一个字母亮起来,代表经过加密之后的字母。&br&&b&转子(Rotor)&/b&:这个是进行加密的部件,具体原理后面解释。&br&&b&插线板(Plugboard)&/b&:这是在转子进行加密后,为了进一步提高安全性而增加的装置。你现在只需要知道有这么个东西就好了,具体原理后面会解释。&br&&br&要想制造出一台在军队中大规模使用的密码机,除了保证密码的复杂程度之外,同时还必须保证操作的简易性,最好随便一个普通士兵在简单训练后都可以马上进行操作。&br&&br&恩格玛机的伟大之处就在于它在进行高度复杂的替换加密的同时,操作的简易性也几乎做到了极致。&br&&br&当一名德军军官将一台恩格玛机设置好之后(它的设置也简单到不像话,后面介绍),只需要随便叫来一个小兵:&br&&br&“二等兵汉斯!过来把这封电报转成密文!”&br&&br&“报告长官,我不会什么加密,我小学只读到了四年级。”&br&&br&“过来坐下,你把这份电报一个字母一个字母的敲到键盘上。每敲一个字母,灯盘上就有一个字母亮起,把亮起的这个字母记录下来。重复这个动作,直到敲完整份电报,然后把得到的密文送到发报室去。还有其他问题吗?很好,开始工作!”&br&&br&你看,不用去德国陆军学院修满20个学时的初级密码学,也不用考过德语四六级,恩格玛机就是这么简单易用老少咸宜。&br&&br&讲完操作方法,我们再来看一下恩格玛机的核心部件——转子:&br&&br&&figure&&img src=&/d7e7e0e38d57aaac4be798b9545e5ebf_b.jpg& data-rawwidth=&1280& data-rawheight=&853& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/d7e7e0e38d57aaac4be798b9545e5ebf_r.jpg&&&/figure&&br&图片的左边是一个完整的转子,右边这些零件是这个转子拆开后内部的样子。&br&&br&转子的工作原理其实非常简单。它的左右两侧各有26个点位,分别代表A-Z这26个字母。信号从一边进去,从另一边出来。但是在制造过程中,位于转子左右两边的26个字母点位被刻意交叉连接,以达到字母替换的目的。例如转子右边代表字母A的点位并没有与左边的A点位相连接,而是被替换成了另外一个字母例如E。图片右边那些一条条的绿色的线路就是连接左右两边点位的电线。&br&&br&下面是两张侧视图,可以更清楚的看到位于转子两侧的26个点位:&br&&br&&figure&&img src=&/13f0785b6bed27a999cffb1f_b.jpg& data-rawwidth=&680& data-rawheight=&710& class=&origin_image zh-lightbox-thumb& width=&680& data-original=&/13f0785b6bed27a999cffb1f_r.jpg&&&/figure&&figure&&img src=&/f49c8d2affdc71d7105233_b.jpg& data-rawwidth=&680& data-rawheight=&710& class=&origin_image zh-lightbox-thumb& width=&680& data-original=&/f49c8d2affdc71d7105233_r.jpg&&&/figure&&br&&br&也就是说,当代表字母A的信号从右侧进入并通过转子后,从左侧出来的时候被替换成了字母E。所以说,&b&单个转子对输入内容所做的本质上是一次单字母替换加密&/b&。由于一个转子被制造出来之后,两侧点位的对应连接关系就无法改变,&b&单个转子只能提供一个固定不变的密码表&/b&。&br&&br&我们前面讲过,单字母替换密码是替换密码中最初级的形式,只要使用字母频率分析就可以轻易破解。很明显,仅仅使用一个转子进行加密是根本行不通的。德国人当然也非常清楚这一点,所以他们在恩格玛机上使用了三个串联在一起的转子,就像这样:&br&&br&&figure&&img src=&/c5ad76c93c5139de6feaf5_b.jpg& data-rawwidth=&800& data-rawheight=&649& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/c5ad76c93c5139de6feaf5_r.jpg&&&/figure&&br&三个转子被串联起来之后,输入的字母被依次这三个转子进行多次替换。在这里大家先不要去过多琢磨这个字母究竟被进行了多少次替换,而是要透过现象看到本质。这个字母在输出到灯盘之前,无论是被替换了五次还是一百次,对于使用者来说,输入26个字母中的每一个字母,都只会得到一个与其对应的、不会改变的替换结果。也就是说,单纯地将三个转子串联起来之后,它们还是只能提供一个固定不变的密码表。&br&&br&但是,当德国人在这三个转子上加入一个新的特性后,它们就可以做到密码师们渴望的&b&每加密一个字母就更换一次密码表&/b&的效果。这个新的特性就是:&br&&br&每输入一个字母之后,第一个转子都会自动转动一格。当第一个转子转完一圈后,会带动第二个转子转动一格。同理,第二个转子在转到特定的位置后,会带动第三个转子转动。&br&&br&由于两个转子之间的连接是通过转子上26个金属点之间的接触来实现的,所以转子转动一次后,整个系统的信号通路就会变换为另外一种组合。&br&&br&由于每个转子都有26中可能的位置,所以三个转子一共可以提供26X26X26=17576个不同的密码表。这个数字已经相当可观了,但德国人还是不满足,又把三个转子设计成可以互相交换位置的形式。三个转子有六种不同的排列方式,所以密码表的数量又增加到了456,也就是大约十万个。德国人还是不满足,又增加了上面图片中的插线板,将密码数量进一步增大了1000亿倍(插线板的原理稍后介绍)。&br&&br&在介绍插线板之前,我们把转子的部分讲完。&br&&br&下面是答主自己画的一张简图,表示了一个信号从被输入转子开始,一直到完成加密后从转子输出的完整路径:&br&&br&&figure&&img src=&/222bc15f8af8ba7e60ad31e836cf0a99_b.jpg& data-rawwidth=&6112& data-rawheight=&3280& class=&origin_image zh-lightbox-thumb& width=&6112& data-original=&/222bc15f8af8ba7e60ad31e836cf0a99_r.jpg&&&/figure&&br&&br&大家可以看到一个字母A从键盘被输入之后,依次被三个转子进行三次替换然后到达反射器(红色路径),在反射器这里又被替换成另外一个字母(绿色路径),接着又沿着一条和来时不同的路径(蓝色路径),然后输出最终的加密结果,即字母G。&br&&br&这个反射器的加入赋予了恩格玛机两个非常非常非常重要的性质:&br&&br&&b&性质一:反射器使得恩格玛机的加密过程是自反的。&/b&也就是说,如果输入字母A得到字母G,那么在机器配置不变的情况下,输入字母G一定会得到字母A。&br&&br&&b&性质二:一个字母加密后的输出结果绝不会是它自身。&/b&&br&&br&如果你看着上面的图片,能自己得出以上两个结论,请跳过下面的补充说明继续阅读。如果无法得出,也不要灰心,请阅读下面的补充说明。&br&&br&====================补充说明开始====================&br&&br&性质一的推导:连接转子正反两面的电线是固定不变的。转子不转动的话,他们相互之间的连接关系也不会改变。换句话说,上图中红色和蓝色的路径都是唯一的,绝不会从中再伸出一条岔路。反射器的内部结构也是固定不变的,意味着绿色的路径也是固定不变的。既然三条路径都是固定不变的,那么信号沿着蓝色路径进入转子,必然会沿着红色路径出来。&br&&br&性质二的推导:我们用反证法来证明。如果想要让一个字母的加密结果是它自身,那么这个字母的信号沿着红色路径到达反射器后,必须再次沿着红色路径返回才行。而这与反射器的工作原理相矛盾,因为反射器的作用就是将输入的信号换一个点位后再输出,以确保其沿着不同的路径返回。&br&&br&====================补充说明结束====================&br&&br&为什么说这两个性质非常非常非常重要呢?&br&&br&性质一这个牛逼的特性意味着恩格玛机不但是加密机,同时也是解密机。也就是说,将明文输入恩格玛机变成密文后,只要把另外一台机器调到初始配置再将密文输入,输出的结果将直接就是明文!真正做到了从八岁到八十岁都可以毫无障碍的使用。&br&&br&第二个性质看起来是一个优点,毕竟把一个字母加密成为自身不就等于没加密吗?但是这个看似是优点的性质日后反而成为了恩格玛机一个重要的漏洞。在破解过程中被破解者们狠狠地利用了一下。&br&&br&转子部分就讲到这里,现在我们来看一下最后一个部件插线板,它是这个样子的:&br&&br&&figure&&img src=&/0c4b7d2bbdbe1bf7c5b0_b.jpg& data-rawwidth=&921& data-rawheight=&627& class=&origin_image zh-lightbox-thumb& width=&921& data-original=&/0c4b7d2bbdbe1bf7c5b0_r.jpg&&&/figure&&br&在插线板上刻有26个字母,如果操作员用一条线将其中两个字母连接起来,那么这两个字母在加密过程中会被互换。例如图片中的字母A和J被连接起来后,当操作员在键盘上敲下字母A后,这个字母A会被替换成J后进入转子。经过转子加密输出后的字母会再一次通过插线板,然后结果被输出到灯盘上。&br&&br&在早期的恩格玛机中,操作员最多可以交换6对字母。在26个字母任意交换6对字母大约有1000亿种组合,也就是说插线板这个简单的设计进一步将恩格玛机所能提供的密钥数量提高了1000亿倍。(对这个计算结果有疑问的,请看这里的详细计算过程:&a href=&///?target=http%3A//www.codesandciphers.org.uk/enigma/steckercount.htm& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&codesandciphers.org.uk/&/span&&span class=&invisible&&enigma/steckercount.htm&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&)&br&&br&我们在前面讲过,三个转子本身可以提供大约十万个密钥,扩大1000亿倍之后就是10^16个密钥。如果使用暴力破解的话,就算一秒钟验算一万个密钥,也需要三万多年才能穷尽所有的组合,而德军一条密钥的使用时间只有24个小时。对于破解者来说,恩格玛机所产生的庞大的密钥数量几乎让人断绝了一切进行暴力破解的念头,更不用提德军在1938年又把转子数量从三个提高到五个,海军后来又干脆提高到了八个。&br&&br&以上,就是恩格玛机的加密原理。&br&&br&在把视角切换到密码破解者一方之前,让我们最后再来看一下恩格玛机在德军中是如何被使用的。&br&&br&恩格玛机的操作员每个月都会收到一本新的密码本,指定本月中每一天所使用的密钥。具体包含三个信息:&br&&br&1)三个转子的排列顺序(例如三个转子从左至右编号分别为2-3-1);&br&2)三个转子的位置(例如三个转子分别转动到Q-V-M);&br&3)插线板的设置(对哪些字母进行交换);&br&&br&只要两台恩格玛机按照上面的三项说明进行相同的初始设置,不管它们之间的物理距离有多远,都可以畅通无阻的进行通讯。&br&&br&恩格玛机所提供的密码系统在那个年代已经是登峰造极了,但有着轻度被迫害妄想症的德国人还是不太放心。虽然每条密钥的使用时间只有区区24小时,但一天之内还是会有成百上千条信息被发出。在本文的第一部分“替换加密的原理和破解方法”中我们也可以看到,敌人截获的密文越长,就越容易发现其中的规律和模式。&br&&br&于是,德国人又采取了一样非常聪明的防范措施:&br&&br&操作员在按照密码本上的指示设置好恩格玛机后,再发送每条信息前,都要随机选取三个字母作为本条信息的新密钥。是的,“随机”的意思指的就是操作员本人在发送信息的这一秒里脑海里浮现出的任意三个字母。&br&&br&假设操作员二等兵汉斯按照密码本的指示设置好了恩格玛机,然后随机选取了TGS这三个字母作为本条信息的密钥。接着,汉斯把这三个字母敲入恩格玛机两遍(敲两遍是为了防止误操作),然后把三个转子的位置分别转到T、G、S这三个位置上开始发送信息的正文。&br&&br&而密码的接收者收到密文之后,会看到密文的前六个字母是BMXYUI。这里需注意由于恩格玛机每输入一个字母就会改变一次密钥,所以汉斯输入的两次TGS被分别加密成了BMX和YUI。接收者把恩格玛机按照密码本设置好之后,把BMXYUI输入,解密后得到本条信息的密钥TGS。这时,接收者会先把恩格玛机的转子转动到TGS的位置,就像几百公里外汉斯做的一样,然后再对信息的正文部分进行解密。&br&&br&这样做的好处是什么呢?通过这种做法,&b&每天的通讯内容中只有每条信息的前六个字母是用密码本上的密钥进行加密的&/b&,而每一条信息的正文都是用不同的密钥进行加密的。如此一来,大大降低了敌人针对每一个密钥所能截获的密文长度。&br&&br&读到这里的各位,已经和密码破解者们拥有差不多相同的信息。换句话说,在试图寻找恩格玛机漏洞这件事上,各位和几十年前的破解者现在站在同一起跑线上。&br&&br&在下一部分,我们将把视角切换到密码的破解者一方,看看他们在恩格玛机上找到了怎样的漏洞。&br&&br&&br&&b&3)恩格玛机的破解&/b&&br&&br&在军用恩格玛机投入使用之后,英法情报机构曾经试着将其破译,结果发现自己就像《格雷的五十度灰》里的女主角一样被虐了个死去活来。经过多次尝试之后,他们宣布这种密码系统是无解的。&br&&br&如果有人正期待着图灵在这一部分的开头闪亮登场,我不得不遗憾地告诉你,破解恩格玛机的第一次突破并不是来自英国人,而是波兰人雷耶夫斯基(Marian Rejewski)。&br&&br&再来总结一下我们第二部分中讲过的内容,想要破译一份被恩格玛机加密的密文,波兰人需要以下三部分信息:&br&&br&a)恩格玛机的工作原理及内部构造,包括每个转子的线路连接;&br&b)德军的对恩格玛机的操作守则;&br&c)德军所使用的每日初始设置。恩格玛机的每日初始设置包含了三个信息:即转子的排列顺序、每个转子的初始位置、以及插线板的设置。这些信息被印刷在密码本上分发至全军,每24小时更换一次设置,每月更换一次密码本;&br&&br&长话短说,通过间谍活动以及出色的数学能力,波兰人得到了a)和b)这两部分信息。&br&&br&接下来,波兰人需要做的就是破解德军所使用的每日初始设置(下文简称为&b&日密钥&/b&)。&br&&br&我们再来回顾一下德国操作员是如何进行一次加密的:&br&&br&首先,操作员会根据日密钥对恩格玛机进行初始设置。例如他会将三个转子的排列顺序按照日密钥的指示排列为2-3-1,然后将三个转子的顺序依次旋转到Q-V-M的位置,最后在插线板上将六对字母进行互换。&br&&br&再发送每一条信息前,操作员都会任意挑选三个此刻在自己脑子中冒出的字母,比如说XYZ,作为&b&本条信息的密钥&/b&,下文称之为&b&信息密钥&/b&。&br&&br&操作员在发送信息前,会先使用日密钥中的设置,也就是转子处在Q-V-M的位置,将XYZ输入两次,得到比如说HGABLE。注意这里随着转子的转动,两次输入的XYZ被加密成了不同的字母。接着,操作员将恩格玛机的三个转子重新转到X-Y-Z的位置,然后将信息的正文输入恩格玛机后发送。&br&&br&处在接收方的操作员,同样是按照日密钥将恩格玛机设置好,然后将信息开始的6个字母HGABLE输入恩格玛机,得到XYZXYZ,那么他就是知道XYZ是加密正文所使用的信息密钥。接下来,他只需将三个转子的位置转到X-Y-Z,然后将剩下的部分输入就会得到信息的正文。&br&&br&这种操作方法的奥秘之处在于,每一条信息的正文都是用不同的密钥进行加密的,从而大大避免了被破解的可能性。只有每条信息的前六个字母是以通用的日密钥加密的。这看起来是一个完美的解决方案,但是雷耶夫斯基用令人难以置信的洞察力,发现了其中的一个漏洞。&br&&br&我们想象雷耶夫斯基截取到了一段德军的电文,前六个字母是HGABLE。他知道这是三个字母连续输入两次恩格玛机后得到的结果。虽然我们不知道这三个字母是什么,但我们知道输出结果HGABLE中第一个字母H和第四个字母B是同一个字母的加密结果。由于转子在期间转动了三次,所以同一个字母在两次加密时被替换成了不同的字母。我们可以把它们组成一对:&br&&br&H - B&br&&br&如果雷耶夫斯基在一天之内截获到了更多的电报,对每封电报的前六个字母进行类似的操作,就会得到更多的字母对,直至26个字母都配上对:&br&&br&H - B&br&A - O&br&……&br&Z - U&br&&br&这看起来只是一个无聊的字母配对游戏而已,跟破解恩格玛机一点关系也没有。但是,雷耶夫斯基凭借非凡的洞察力,利用每条信息前这区区六个字母,找到了破解之道。&br&&br&答主看到很多人在评论区里很淡定的表示这篇文章一点都不烧脑。答主在这里想说,嗯,那是因为本文真正烧脑的内容根本还没开始呀……&br&&br&在阐述雷耶夫斯基的思路之前,我需要大家认真地思考一个问题:&br&&br&恩格玛机的本质究竟是什么?&br&&br&你在恩格玛机上敲入一个字母,它会输出另外一个字母。这就是恩格玛机的本质:字母替换。&br&&br&在一个相同的设置下,你敲入26个字母中随便哪一个字母,所得到的替换字母都是确定不变的。我们可以将这个替换关系用函数(A0)来表示。你也许会说,恩格玛机是很复杂的,每敲下一个字母后,转子会转动一位,然后就是一种完全不同的替换关系。没关系啊,我们可以把转动一位之后的替换关系用(A1)来表示。类似的,我们用(A2)来表示转子转动两位之后的替换关系用,一直到(A5)表示转子转动五位之后的。&br&&br&答主在本文中已经最大限度的避免使用数学符号和公示,但在雷耶夫斯基的思路过于抽象,借助一些函数符号反而有助于理解。当你充分理解上一段话的意思之后,让我们再来看一下波兰人截获的六位字母HGABLE。波兰人并不知道这是哪三个字母被加密两次的结果,不过没关系,我们暂且假设它为XYZ。这样,我们可以利用上面的替换关系将加密过程表示为:&br&&br&X(A0)=H&br&Y(A1)=G&br&Z(A2)=A&br&X(A3)=B&br&Y(A4)=L&br&Z(A5)=E&br&&br&还记得在本文的第二部分,我们提到的恩格玛机的两个非常非常重要的性质吗?其中第一条是恩格玛机是&b&自反&/b&的。就是说,如果输入字母A得到字母G,同样的配置下输入字母G就会得到字母A,这同时也是恩格玛机解密的原理。如果用刚才的函数来表示的话就是,一个字母被函数(An)连续替换两次会得到自身,比如:&br&&br&X(A0)(A0)=X&br&&br&嗯,好像开始有点意思了,如果我们把前面第四行式子X(A3)=B中的X写成上面这种形式的话,会得到:&br&&br&X(A0)(A0)(A3)=B&br&&br&然后从第一行我们已经知道X(A0)=H,所以:&br&&br&H(A0)(A3)=B&br&&br&神奇的事情发生了,X这个字母被抵消掉了!也就是说,雷耶夫斯基发现的&b&H和B之间的这种联系与用来加密每一条信息的信息密钥是无关的&/b&。这种联系只与恩格玛机在这一天的初始配置相关。在这里,雷耶夫斯基不知道(A0)是什么,也不知道(A3)是什么,但通过前面的字母配对游戏中其他的24个字母之间的替换关系,雷耶夫斯基可以推导出(A0)(A3)。这个(A0)(A3)所代表的正是是雷耶夫斯基前面所做的那个字母配对游戏中,横线左边的字母被替换成右边的这样一种替换关系。&br&&br&(A0)(A3)的物理意义就是将一个字母通过恩格玛机的初始设置进行替换后,再将转子向后转动三位将所得的结果再进行一次替换。如果忽略掉中间步骤,从本质上讲它还是一种替换,与本文开头所介绍的最简单的单字母替换密码没有区别,一样可以被写成下面这种形式:&br&&figure&&img src=&/40d69bb8ebd39d3fd3b907f0f73992f0_b.jpg& data-rawwidth=&7504& data-rawheight=&792& class=&origin_image zh-lightbox-thumb& width=&7504& data-original=&/40d69bb8ebd39d3fd3b907f0f73992f0_r.jpg&&&/figure&&br&如果我们已经知道了(A0)(A3)所代表的的就是上图这样的替换关系,可以用这个结果对恩格玛机进行暴力破解吗?如果没有插线板的话,这种做法理论上讲是可行的。对于处于任意状态的恩格玛机,我们可以测试每一个字母经过“初始位置”和“旋转三位后位置”两次加密后是否得到了正确的结果。三个转子的排列和初始位置一共有大约十万种可能性,如果制造100台恩格玛机,由100个人同时进行暴力破解,每人10秒钟完成一次检查的话,可以在三个小时内完成暴力破解。&br&&br&但是由于插线板的存在,将可能的组合数量一下子增加了1000亿倍,彻底地杜绝了一切暴力破解的可能性。在这个时候,雷耶夫斯基又找到了一个方法,巧妙地消除了插线板的影响。&br&&br&我们来做一个小练习,假设有一个替换密码表,我们一般会把它写成下面的形式(为了方便演示,我这里使用一个只有八个字母的密码):&br&&br&明文
H&br&密文 C
G&br&&br&我们可以做一个首尾接龙的游戏。比如上表中明文A被替换成密文C,那么我们在第一行中再找到C,发现C被替换成了E,那么在第一行中找到E,发现E被替换回了A,这样我们就完成了一个字母链条。然后我们换一个在上一个链条中没出现过的字母重新开始,直到所有的字母都被列入一个链条。我们将处于同一个链条中的字母写入一个括号内,这个密码表就变成:&br&&br&(A, C, E) (B, H, G, D, F) &br&&br&与原先的形式相比,写成这种形式的密码表传递了完全相同的信息。你一样可以知道A应该被替换成C,C应该被替换成E,E应该被替换成A……等等。那么写成这种形式有什么好处呢?这种形式可以揭示一个密码表的一个内在特征,比如上面这个密码表是由两条字母链条组成的,链条长度分别为“3”和“5”。这个“3”和“5”就是这个密码表的特征值。&br&&br&如果将我们之前得到的(A0)(A3)也改写成这种链条形式的话,会得到这样的结果:&br&&br&(A, C, M, Y, N, Z, Q, D, P, B, O) (E, U, I, S, G) (F, T, H, R) (J, V) (K, W) (L, X)&br&&br&可见,这个(A0)(A3)所对应的密码表一共由6个字母链条组成,长度分别是“11”、“5”、“4”、“2”、“2”、“2”。&br&&br&插线板可以将恩格玛机设置的组合数量提高1000亿倍,也可以将密码表中的字母替换地面目全非。但由于插线板是将字母成对地进行交换,这种交换方式不会改变密码表的链条数量及长度。在上面写成链条形式的密码表中,任意交换两个字母的位置,无论交换多少次也不会改变链条的数量和长度。&br&&br&就这样,雷耶夫斯基成功地找到了绕开插线板的方法。&br&&br&对应恩格玛机转子设置十万种可能的组合,波兰人对每一种组合所产生的字母链条数量和长度进行了分类(说起来容易,这花了一年的时间)。有了这样一个分类目录,波兰人就可以按照以下步骤进行破解:&br&&br&a) 首先根据当日截获的每一封电报的前六个字母推导出字母链条的数量和长度&br&b) 接着在分类目录里找到相应的可能转子设置(一个比十万小得多的数量)&br&c) 针对所有可能的转子设置进行暴力破解。&br&&br&到这里,波兰人已经拿到了德军日密钥中除了插线板设置以外所有的内容。&br&&br&得到转子的设置之后,雷耶夫斯基将会把一台恩格玛机按照这种设置装好,但是插线板完全不插任何电线,然后把一段密文输入这台机子。他会得到一段没有意义的信息,因为信息中的六对字母被随机对调了。但是这种字母互换只是一种非常初级的加密方式,可以使用人工轻松地破解。这样,破解者又拿到了插线板设置。&br&&br&这样,波兰人拿到了德军&b&日密钥中的全部内容&/b&。也就是说,雷耶夫斯基与德军中的接收员处在了完全对等的地位,德军所有的通讯对于波兰人来说都是完全透明的——至少在当天午夜十二点之前是这样。&br&&br&如果恩格玛机就这样被波兰人破解了,那还关图灵什么事呢?&br&&br&德军在二战爆发前后,又采取了很多措施来加强恩格玛机的安全性(变态啊),其中的一些使得波兰人上面的这种破解方法失效:&br&&br&a) 日开始,德军干脆连日密钥中的转子位置也让操作员自己选择。这样一来,就连每条信息的前六个字母也变成是用不同密钥加密的了。&br&b) 日,德军把转子的数量从三个增加到了五个,安装的时候从五个里面随机选三个安装在恩格玛机上,将可能的转子组合增加了10倍。更重要的是,有了多出来的转子,波兰人做的分类目录就失效了。&br&c) 日,德军把插线板上交换字母的最大数量从6对增加到了10对。&br&d) 日,德军规定每条信息的信息密钥发送一遍即可,无需重复两次。&br&&br&接下来,该英国人出场了。&br&&br&================补充说明开始的分割线==============&br&&br&在图灵正式出场之前,由于评论里有好几个人表示上面德军新操作守则里的a)看不懂,答主在这里再简单说明一下。&br&&br&在后期的恩格玛机中,德军又对转子进行了改造,使得转子芯外面的字母圈可以绕着转子旋转。这样一来,德军的日密钥内容就变成了以下三个部分:&br&&br&1) 从五个转子中选择三个特定的转子,并按一定顺序排列;&br&2) 每个转子外侧的字母圈相对于转子芯的位置;&br&3) 插线板所交换的10对字母;&br&&br&这里请大家注意,在德军实行新规定之后,日密钥中已经不存在每日通用的转子初始位置。在发送每一条信息前,操作员都要自己选择&b&转子初始位置&/b&,然后再自己选择本条信息的&b&信息密钥&/b&。&br&&br&举例来说,操作员按照密码本上的日期对恩格玛机完成三项设置后,准备发送一条信息。在发送前,他选择了ABC和XYZ分别作为&b&转子初始位置&/b&和&b&信息密钥&/b&。他首先把恩格玛机的三个转子拨动到A-B-C的位置上,键入两次XYZ后得到HBLZQO,这样就完成了对信息密钥的加密。接着他把恩格玛机的转子拨动到X-Y-Z的位置上继续输入信息的正文。&br&&br&评论区很多人的问题是那么这个操作员怎样把ABC这个转子初始位置发送给接收方呢?答案是用明文发送。&b&是的,你没看错,就是明文发送!&/b&所以操作员将会依次以明文发送ABC,接着是加密过的HBLZQO,最后是以信息密钥加密后的信息正文。&br&&br&接收方收到以上信息后,会首先将恩格玛机拨动到ABC的位置,键入HBLZQO后得到XYZXYZ,于是他知道接下来的信息正文是用密钥XYZ加密的。接着他只要把恩格玛机转动到XYZ的位置键入密文,就可以得到信息的明文。&br&&br&就算破解者截获到这段电报并且知道ABC是明文,也无法知道本条信息的信息密钥。因为破解者不知道德国人手中恩格玛机上的字母圈相对于转子被旋转了多少位,所以并不知道ABC所对应的转子真实位置到底是什么。&br&&br&雷耶夫斯基巧妙的利用了德军“每条信息的前六个字母都是用同一个通用密钥加密”这一点来进行破解。但是德军采取上述做法之后,每条信息前面的这六位字母都变成是用不同的密钥加密的。所以雷耶夫斯基的破解方法也随之失效。&br&&br&不过,这个时候的波兰人又想出了另外一种有效的方法进行破解(人类智力的潜能真是无穷无尽啊),直到1940年德国人规定信息密钥只需输入一次后,才彻底失效。考虑到本文的篇幅,这里就不做介绍了。&br&&br&================补充说明结束的分割线==============&br&&br&在1939年德军入侵波兰前夕,波兰人将恩格玛机的复制品以及他们所掌握的破解方法提供给了英法两国。波兰人向英国人证明了恩格玛并不是一种完美无缺的密码系统,并且表明了数学知识在破解中的重要性。&br&&br&不知道英国人在得知波兰人的工作成果之后是怎样的心情,也许震惊之余还会夹杂着一点点惭愧吧。这可是曾经培育出牛顿的国度,在之前竟然如此轻易就放弃了尝试。&br&&br&波兰人对于英国人士气的激励更多的是在心理层面而不是在技术层面。图灵虽然赞叹波兰人的智慧,但也清醒地认识到波兰人的破解方法过于依赖德国人操作方式上的漏洞。一旦德国人停止将信息密钥重复输入两次,这种破解方法将在一夜之间彻底失效。图灵所追求的破解方式是一种更加纯粹、更加直接的暴力破解。&br&&br&如果说波兰人是利用敌人防线上的漏洞进行伞兵奇袭,那么图灵想要的更像是步兵师的正面对抗。机器创造出来的密码怪兽,只有用机器才能战胜。而人类的任务不过是设计机器的工作原理以及优化机器所要进行的运算量。&br&&br&做了这么长的铺垫,终于要进入大结局了。我们来一起看一下英国人的破解恩格玛机的。&br&&br&首先,英国人需要在密文中确定一条“Crib”。所谓Crib,指的是一段猜测出来的明文与密文中字母的一一对应关系。在密文中猜测出几个单词的明文并不困难,因为循规蹈矩的德国人在信息正文中喜欢用固定的词组,比如Keine besonderen Ereignisse(无特殊情况),Heil Hitler(希特勒万岁)等。另外一个例子是英国人发现德国人喜欢在早上6点钟发送一条天气预报,所以在早上6点钟截获的电文开头中肯定包含wetter(天气)这个词。&br&&br&猜出密文中包含的明文单词后,如何精确地确定它们的位置呢?希望你还没有忘记我们前面讲过的恩格玛机的第二个非常非常重要的性质,那就是一个字母永远不会被替换为自身。根据恩格玛机的这个特性,我们可以把一段明文字母在猜测对应的密文上方来回移动进行判断。下面我们用德文单词wetter做一个简单的示例:&br&&br&&figure&&img src=&/919de9cbb11a2a84e0a5d01_b.jpg& data-rawwidth=&3720& data-rawheight=&1664& class=&origin_image zh-lightbox-thumb& width=&3720& data-original=&/919de9cbb11a2a84e0a5d01_r.jpg&&&/figure&&br&在上面这张图片中,明文位置1可以被排除掉,因为在这个位置上明文中的E又被加密成了E,而这是违反恩格玛机特性的。同理,明文位置3也可以被排除掉,因为明文中的R又被加密成了R。排除掉不可能的情况,明文位置2就极有可能是wetter这个单词所处的真实位置。这样我们就得到了一个Crib,其中明文与密文的对应关系如下:&br&&br&明文 W E T T E R&br&密文 E R K M G W&br&&br&在上面的对应关系中,图灵利用其中首尾相接的字母链,设计出了可以暴力破解恩格玛机的机器。在这段Crib中,明文中的W被加密成E,转子转动一位后E被加密成R,转子转动五位之后R又被加密成W。我们可以把它们之间的关系表示成下面的样子:&br&&br&W -& 转子位置0加密 -& E -& 转子位置1加密 -& R -& 转子位置5加密 -& W&br&&br&我们来详细观察一下恩格玛机将字母W加密成字母E这个过程:&br&&br&&figure&&img src=&/1ffccebce62a_b.jpg& data-rawwidth=&7200& data-rawheight=&1896& class=&origin_image zh-lightbox-thumb& width=&7200& data-original=&/1ffccebce62a_r.jpg&&&/figure&&br&当操作员在键盘上敲下W这个字母后,它首先被插线板替换成了另外一个字母(也有可能没替换),我们把这个结果记为v1,接着v1进入了三个转子又被替换成了v2,最后v2重新进入插线板被替换成了字母E。在这里我们并不知道v1和v2究竟是什么字母,不过这并不影响我们对以上工作原理的理解。&br&&br&在W-E-R-W这个字母链中,我们想象有三台恩格玛机被插入到这三个字母之间并形成一个循环:&br&&br&&figure&&img src=&/94cd325e40ae8c094aec4bce0ca29520_b.jpg& data-rawwidth=&5008& data-rawheight=&4488& class=&origin_image zh-lightbox-thumb& width=&5008& data-original=&/94cd325e40ae8c094aec4bce0ca29520_r.jpg&&&/figure&上面这个循环完整的表示了字母W被加密成E,E被加密成R,R又被加密成W这一过程。其中v1,v2,v3,v4都涉及到插线板的替换,由于我们现在还不知道插线板的设置,所以也无法知道这四个字母是什么。不过,由于插线板的设置在整个加密过程中是不变的,所以既然W通过插线板被替换v1,而v4通过插线板被替换成W,我们从而可以肯定&b&v1=v4&/b&。这个结论在图中用红色方框标出。另外,在这个循环过程中,v2先是通过插线板被替换成了E,紧接着又在进入第二台恩格玛机后被插线板替换回了v2。我们可以干脆省略掉这一步,让v2直接进入第二台恩格玛机的转子。对于v3也我们也可以做类似的省略,所以上图可以被简化为:&br&&br&&figure&&img src=&/43eb75ecddc9_b.jpg& data-rawwidth=&5696& data-rawheight=&5536& class=&origin_image zh-lightbox-thumb& width=&5696& data-original=&/43eb75ecddc9_r.jpg&&&/figure&图灵现在只要输入v1(图中假设v1=K),然后试着让这个v1先后通过三台恩格玛机的转子部分得到一个输出结果v4,并对这个结果进行检查。如果v1不等于v4,那么说明目前的恩格玛机转子设置是错误的。如果v1=v4,那么当前的恩格玛机设置有可能是正确的。&br&&br&虽然图中出现了三台恩格玛机,但由于它们之间的转子位置差距已经确定,所以总的组合数只有60X26X26X26=1054560种。我们再一次看到,只要绕开插线板的干扰,所要检查的转子组合总数立即就下降到了一个可以接受的范围。图灵只要针对这约一百万中组合进行暴力破解,就可以找到所有可能的转子设置组合。如果Crib能够提供足够多的字母链,甚至可以直接锁定唯一可能的转子设置。&br&&br&什么?你说图灵不知道v1是什么字母?无非只有26种可能性而已,图灵只要在这个地方插上26根电线同时对26个字母进行测试就可以了。&br&&br&图灵所设计的机器“炸弹”(bombe)就是利用上面的原理对恩格玛密码系统进行了暴力破解。下面我们来看一下炸弹长什么样子,直接上维基百科图:&br&&br&&figure&&img src=&/caa505559a_b.jpg& data-rawwidth=&678& data-rawheight=&1024& class=&origin_image zh-lightbox-thumb& width=&678& data-original=&/caa505559a_r.jpg&&&/figure&&br&大家在上面的图中可以看到很多三个一组的转盘,这里面每一个转盘都相当于恩格玛机中的一个转子,所以每组转盘就相当于一台恩格玛机。一台标准的“炸弹”一共有36组这样的转盘。&br&&br&英国人把准备好的Crib输入“炸弹”后,机器就会根据输入的内容进行暴力破解,如果遇到可能的解,它就会停止下来供工作人员停下来记录结果。而当它没有停下来的时候,人类所能做的就只有站在旁边等待——因为机器创造出来的密码怪兽,只有机器才能战胜。&br&&br&以上。&br&&br&PS:评论区里有人留言说答主没有解释原问题中关于德军女友名字Cally对于英军有什么用。我没有看这部电影,但是猜测这里指的应该是很多德军发报员在被要求随机选择三个字母作为信息密钥的时候,为了省事就在键盘上上随便敲下ABC或者XYZ这样简单的组合,也有人为了方便记忆就干脆直接自己女友名字的前三个字母。&br&&br&出现这样的现象并不是恩格玛机本身的问题,而是人性的弱点造成的。英军在发现这一现象后,就针对以上这些常见的组合进行优先破解,从而缩短获取密钥的时间。&br&&br&=================答后的分割线==================&br&&br&写到凌晨一点钟,答主终于填完这个坑了。&br&&br&如果有人因为答主之前没写完而留着赞,别犹豫了,狠狠地点上去吧,千万别跟我客气。&br&&br&另外,对类似话题有兴趣的可以去看楼主对于一个相关问题的回答:&br&&br&&a href=&/question//answer/& class=&internal&&失传的古文字(象形文字、楔形文字等)最初是如何被破译的?如何确认译文的正确性? - 十一点半的回答&/a&&br&&br&再次谢谢各位支持。
首先声明一下,答主没有看过《模仿游戏》这部电影,不知道这部影片中有多少演绎的成分,所以只是根据史实讲述一下二战中德军的恩格玛机(Enigma machine)是如何被破解的。 好,我们开始。 想要理解恩格玛机是如何被破解的,首先要理解这种机器的加密原理。…
一句话先回答问题:&b&因为斐波那契数列在数学和生活以及自然界中都非常有用。&/b&&br&&br&下面我就尽我所能,讲述一下斐波那契数列。&br&&br&&b&一、起源和定义&/b&&br&&br&斐波那契数列最早被提出是印度数学家Gopala,他在研究箱子包装物件长度恰好为1和2时的方法数时首先描述了这个数列。也就是这个问题:&br&&br&&blockquote&有n个台阶,你每次只能跨一阶或两阶,上楼有几种方法?&br&&/blockquote&&br&而最早研究这个数列的当然就是&a href=&///?target=http%3A//zh.wikipedia.org/wiki/%25E6%E6%25B3%25A2%25E9%%25E5%25A5%2591& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&斐波那契&i class=&icon-external&&&/i&&/a&(Leonardo Fibonacci)了,他当时是为了描述如下情况的兔子生长数目:&br&&br&&blockquote&&ul&&li&第一个月初有一对刚诞生的兔子&/li&&li&第二个月之后(第三个月初)它们可以生育&/li&&li&每月每对可生育的兔子会诞生下一对新兔子&/li&&li&兔子永不死去&/li&&/ul&&/blockquote&&br&&figure&&img src=&/d4816eea15e9_b.jpg& data-rawwidth=&531& data-rawheight=&298& class=&origin_image zh-lightbox-thumb& width=&531& data-original=&/d4816eea15e9_r.jpg&&&/figure&&br&这个数列出自他赫赫有名的大作《计算之书》(没有维基词条,坑),后来就被广泛的应用于各种场合了。这个数列是这么定义的:&br&&br&&figure&&img src=&/46c741e0cabc54bc_b.jpg& data-rawwidth=&469& data-rawheight=&122& class=&origin_image zh-lightbox-thumb& width=&469& data-original=&/46c741e0cabc54bc_r.jpg&&&/figure&&br&&a href=&///?target=http%3A//oeis.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The On-Line Encyclopedia of Integer Sequences(R) (OEIS(R))&i class=&icon-external&&&/i&&/a&序号为&a href=&///?target=http%3A//oeis.org/A000045& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&A000045 - OEIS&i class=&icon-external&&&/i&&/a&&br&&br&(注意,并非满足第三条的都是斐波那契数列,&a href=&///?target=http%3A//zh.wikipedia.org/wiki/%25E5%258D%25A2%25E5%258D%25A1%25E6%2596%25AF%25E6%%25E5%& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&卢卡斯数列&i class=&icon-external&&&/i&&/a&(&a href=&///?target=http%3A//oeis.org/A000032& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&A000032 - OEIS&i class=&icon-external&&&/i&&/a&)也满足这一特点,但初始项定义不同)&br&&br&&b&二、求解方法&/b&&br&&br&讲完了定义,再来说一说如何求对应的项。斐波那契数列是编程书中讲递归必提的,因为它是按照递归定义的。所以我们就从递归开始讲起。&br&&br&1.递归求解&br&&br&&div class=&highlight&&&pre&&code class=&language-c&&&span class=&kt&&int&/span& &span class=&nf&&Fib&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&n&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&n&&n&/span& &span class=&o&&&&/span& &span class=&mi&&2&/span& &span class=&o&&?&/span& &span class=&mi&&1&/span& &span class=&o&&:&/span& &span class=&p&&(&/span&&span class=&n&&Fib&/span&&span class=&p&&(&/span&&span class=&n&&n&/span&&span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&)&/span& &span class=&o&&+&/span& &span class=&n&&Fib&/span&&span class=&p&&(&/span&&span class=&n&&n&/span&&span class=&o&&-&/span&&span class=&mi&&2&/span&&span class=&p&&));&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&br&这是编程最方便的解法,当然,也是效率最低的解法,原因是会出现大量的重复计算。为了避免这种情况,可以采用递推的方式。&br&&br&2.递推求解&br&&br&&div class=&highlight&&&pre&&code class=&language-c&&&span class=&kt&&int&/span& &span class=&n&&Fib&/span&&span class=&p&&[&/span&&span class=&mi&&1000&/span&&span class=&p&&];&/span&
&span class=&n&&Fib&/span&&span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&&span class=&n&&Fib&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&i&/span& &span class=&o&&=&/span& &span class=&mi&&2&/span&&span class=&p&&;&/span&&span class=&n&&i&/span& &span class=&o&&&&/span& &span class=&mi&&1000&/span&&span class=&p&&;&/span&&span class=&n&&i&/span&&span class=&o&&++&/span&&span class=&p&&)&/span& &span class=&n&&Fib&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&Fib&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&]&/span& &span class=&o&&+&/span& &span class=&n&&Fib&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&o&&-&/span&&span class=&mi&&2&/span&&span class=&p&&];&/span&
&/code&&/pre&&/div&&br&递推的方法可以在O(n)的时间内求出Fib(n)的值。但是这实际还是不够好,因为当n很大时这个算法还是无能为力的。接下来就要来讲一个有意思的东西:矩阵。&br&&br&3.矩阵递推关系&br&&br&学过代数的人可以看出,下面这个式子是成立的:&br&&img src=&///equation?tex=%5Cbegin%7Bbmatrix%7D%0AFib%28n%2B1%29+%5C%5C%0AFib%28n%29%0A%5Cend+%7Bbmatrix%7D%0A%3D%5Cbegin%7Bbmatrix%7D%0A1%261+%5C%5C%0A1%260%0A%5Cend%7Bbmatrix%7D%0A%5Cbegin%7Bbmatrix%7D%0AFib%28n%29+%5C%5C%0AFib%28n-1%29%0A%5Cend%7Bbmatrix%7D& alt=&\begin{bmatrix}
Fib(n+1) \\
\end {bmatrix}
=\begin{bmatrix}
\end{bmatrix}
\begin{bmatrix}
\end{bmatrix}& eeimg=&1&&&br&不停地利用这个式子迭代右边的列向量,会得到下面的式子:&br&&img src=&///equation?tex=%5Cbegin%7Bbmatrix%7D%0AFib%28n%2B1%29+%5C%5C%0AFib%28n%29%0A%5Cend+%7Bbmatrix%7D%0A%3D%5Cbegin%7Bbmatrix%7D%0A1%261+%5C%5C%0A1%260%0A%5Cend%7Bbmatrix%7D%5E%7Bn%7D%0A%5Cbegin%7Bbmatrix%7D%0AFib%281%29+%5C%5C%0AFib%280%29%0A%5Cend%7Bbmatrix%7D& alt=&\begin{bmatrix}
Fib(n+1) \\
\end {bmatrix}
=\begin{bmatrix}
\end{bmatrix}^{n}
\begin{bmatrix}
\end{bmatrix}& eeimg=&1&&&br&这样,问题就转化为如何计算这个矩阵的n次方了,可以采用快速幂的方法。&a href=&///?target=http%3A///link%3Furl%3Ddbyx1Lo9P_Ca2cRdKuttAobLhFrmlyfGuCYn1MnzHvOVu-QwilkS3guqyxSZNXIWxlW8s9IIPAgf2_swv093Hq& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&快速幂_百度百科&i class=&icon-external&&&/i&&/a&是利用结合律快速计算幂次的方法。比如我要计算&img src=&///equation?tex=2%5E%7B20%7D+& alt=&2^{20} & eeimg=&1&&,我们知道&img src=&///equation?tex=2%5E%7B20%7D+%3D++2%5E%7B16%7D+%2A+2%5E%7B4%7D++& alt=&2^{20} =
2^{16} * 2^{4}
& eeimg=&1&&,而&img src=&///equation?tex=2%5E%7B2%7D+& alt=&2^{2} & eeimg=&1&&可以通过&img src=&///equation?tex=2%5E%7B1%7D+%5Ctimes+2%5E%7B1%7D+& alt=&2^{1} \times 2^{1} & eeimg=&1&&来计算,&img src=&///equation?tex=2%5E%7B4%7D+& alt=&2^{4} & eeimg=&1&&而可以通过&img src=&///equation?tex=2%5E%7B2%7D%5Ctimes+2%5E%7B2%7D++& alt=&2^{2}\times 2^{2}
& eeimg=&1&&计算,以此类推。通过这种方法,可以在O(lbn)的时间里计算出一个数的n次幂。快速幂的代码如下:&br&&div class=&highlight&&&pre&&code class=&language-c&&&span class=&kt&&int&/span& &span class=&nf&&Qpow&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&a&/span&&span class=&p&&,&/span&&span class=&kt&&int&/span& &span class=&n&&n&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&kt&&int&/span& &span class=&n&&ans&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&k&&while&/span&&span class=&p&&(&/span&&span class=&n&&n&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&n&&n&/span&&span class=&o&&&&/span&&span class=&mi&&1&/span&&span class=&p&&)&/span& &span class=&n&&ans&/span& &span class=&o&&*=&/span& &span class=&n&&a&/span&&span class=&p&&;&/span&
&span class=&n&&a&/span& &span class=&o&&*=&/span& &span class=&n&&a&/span&&span class=&p&&;&/span&
&span class=&n&&n&/span& &span class=&o&&&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&k&&return&/span& &span class=&n&&ans&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&将上述代码中的整型变量a变成矩阵,数的乘法变成矩阵乘法,就是矩阵快速幂了。比如用矩阵快速幂计算斐波那契数列:&br&&br&&div class=&highlight&&&pre&&code class=&language-c&&&span class=&cp&&#include &cstdio&&/span&
&span class=&cp&&#include &iostream&&/span&
&span class=&n&&using&/span& &span class=&n&&namespace&/span& &span class=&n&&std&/span&&span class=&p&&;&/span&
&span class=&k&&const&/span& &span class=&kt&&int&/span& &span class=&n&&MOD&/span& &span class=&o&&=&/span& &span class=&mi&&10000&/span&&span class=&p&&;&/span&
&span class=&k&&struct&/span& &span class=&n&&matrix&/span&&span class=&c1&&//定义矩阵结构体&/span&
&span class=&p&&{&/span&
&span class=&kt&&int&/span& &span class=&n&&m&/span&&span class=&p&&[&/span&&span class=&mi&&2&/span&&span class=&p&&][&/span&&span class=&mi&&2&/span&&span class=&p&&];&/span&
&span class=&p&&}&/span&&span class=&n&&ans&/span&&span class=&p&&,&/span& &span class=&n&&base&/span&&span class=&p&&;&/span&
&span class=&n&&matrix&/span& &span class=&nf&&multi&/span&&span class=&p&&(&/span&&span class=&n&&matrix&/span& &span class=&n&&a&/span&&span class=&p&&,&/span& &span class=&n&&matrix&/span& &span class=&n&&b&/span&&span class=&p&&)&/span&&span class=&c1&&//定义矩阵乘法&/span&
&span class=&p&&{&/span&
&span class=&n&&matrix&/span& &span class=&n&&tmp&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&i&/span& &span class=&o&&=&/span& &span class=&mi&

我要回帖

更多关于 崩坏学园 的文章

 

随机推荐