简体   繁体   English

解密 Javascript 中的 3 步密码会导致字母表中 26 个字符中仅显示一半,而一些字符最终会显示为符号

[英]Decryption of a 3-step cipher in Javascript leads to only half of the 26 characters in the alphabet being show, while some end up as symbols

So I have a project where I need to create a cipher which has 3 different types of ciphers built into it.所以我有一个项目,我需要创建一个密码,其中内置了 3 种不同类型的密码。 In my case I have a Caesar cipher, Atbash cipher and ROT13.就我而言,我有一个凯撒密码、阿特巴什密码和 ROT13。 Whenever I try to decrypt a message however, some characters don't show up, while some show up as symbols.但是,每当我尝试解密消息时,有些字符不会显示,而有些则显示为符号。

Below is my code in Javascript下面是我在 Javascript 中的代码

function decryptROT13() { 
    var dmsg = document.getElementById('message').value;
    var dnewMsg2 = '';
    for(var i = 0; i < dmsg.length; i++){
    var n = dmsg.charCodeAt(i)

    if(n == 32) {
        dnewMsg2 += String.fromCharCode(n);
    }

    else if(n - 13 > 90){
        dnewMsg2 += String.fromCharCode(n-13-26)
    }

    else{
        dnewMsg2 += String.fromCharCode(n - 13)
        }

    }
    decryptAtbash(dnewMsg2);
}

function decryptAtbash(dval) { 
    var dmsg = dval;
    var dnewMsg1 = '';
    var dtebahpla = 'ZYXWVUTSRQPONMLKJIHGFEDCBA ';
    var dalphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ';     

    for (i = 0; i < dmsg.length; i++) {
        var dcodedLetter = dmsg.charAt(i);
        var dletterIndex = dalphabet.indexOf(dcodedLetter);
        dnewMsg1 += dalphabet.charAt(dletterIndex); 
        }
        
     decryptCaesar(dnewMsg1); 

}


function decryptCaesar(dval) {  
    var dnewMsg = '';
    var dmsg = dval;
    var dmsg1 = dmsg.toUpperCase();
    for(var i = 0; i < dmsg1.length; i++){
        var n = dmsg1.charCodeAt(i)

    if(n == 32) {
        dnewMsg += String.fromCharCode(n);
    }

    else if(n - 3 > 90){
        dnewMsg += String.fromCharCode(n - 3 - 26)
    }

    else{
        dnewMsg += String.fromCharCode(n - 3)
        }
    }
    dnewMsg.toUpperCase()
    document.getElementById('decryptedMessage').innerHTML = dnewMsg;
}

This what the output looks like:这就是 output 的样子:

这就是输出的样子

character codes字符代码

Our simple ciphers will work on capital letters AZ and perform simple transformations of their ASCII character codes.我们的简单密码将处理大写字母 AZ 并对其 ASCII 字符代码执行简单的转换。 We can go from a letter to a character code -我们可以 go 从一个字母到一个字符代码 -

console.log("A".charCodeAt(0)) // 65
console.log("B".charCodeAt(0)) // 66
console.log("C".charCodeAt(0)) // 67
console.log("Z".charCodeAt(0)) // 90

Or from a character code to a letter -或者从一个字符代码到一个字母——

console.log(String.fromCharCode(65)) // "A"
console.log(String.fromCharCode(66)) // "B"
console.log(String.fromCharCode(67)) // "C"
console.log(String.fromCharCode(90)) // "Z"

We will write reusable functions toCode and fromCode to simplify the rest of our program -我们将编写可重用的函数toCodefromCode来简化我们程序的 rest -

const toCode = s =>
  s.toUpperCase().charCodeAt(0)

const fromCode = n =>
  String.fromCharCode(n)

cipher密码

A cipher is an isomorphism - ie, it is a pair of functions whereby one function can reverse the effect of the other. cipher是一种同构- 即,它是一对函数,其中一个 function 可以反转另一个的效果。 Each cipher we write will have an encode and decode function -我们编写的每个密码都有一个encodedecode function -

const cipher = (encode, decode) =>
  ({ encode, decode })

Character A starts at offset 65 , Z ends at 90 , and we don't want to apply our cipher to characters out of this range.字符A从偏移量65开始, Z90结束,我们不想将密码应用于超出此范围的字符。 Instead of handling this logic in each cipher, it would be nice if we could write our ciphers that work on a simple AZ charset that goes from 0-25 -如果我们可以编写适用于从 0-25 的简单 AZ 字符集运行的密码,而不是在每个密码中处理此逻辑,那就太好了 -

(0,A) (1,B) (2,C) (3,D) (4,E)
(5,F) (6,G) (7,H) (8,I) (9,J)
(10,K) (11,L) (12,M) (13,N) (14,O)
(15,P) (16,Q) (17,R) (18,S) (19,T)
(20,U) (21,V) (22,W) (23,X) (24,Y)
(25,Z)

For any given alg orithm and character code n , we can filter characters that are out of the 65-90 range, and automatically apply appropriate offset to the algorithm's response -对于任何给定的alg和字符代码n ,我们可以filter超出 65-90 范围的字符,并自动将适当的偏移量应用于算法的响应 -

const filter = alg => n =>
  n < 65 || n > 90      // if n is out or range
    ? n                 // simply return n
    : 65 + alg(n - 65)  // apply offset to alg's response

atbash阿特巴什

Now let's write our first cipher, atbash -现在让我们编写我们的第一个密码atbash -

atbash(n) atbash(n) cipher密码
25 - 0 = 25 25 - 0 = 25 A → Z A → Z
25 - 1 = 24 25 - 1 = 24 B → Y B → Y
25 - 2 = 23 25 - 2 = 23 C → X C → X
25 - 23 = 2 25 - 23 = 2 X → C X → C
25 - 24 = 1 25 - 24 = 1 Y → B Y → B
25 - 25 = 0 25 - 25 = 0 Z → A Z → A

The implementation is simple.实现很简单。 As the table above reveals, the process to encode atbash is exactly the same as the decoding process.如上表所示,对 atbash 进行编码的过程与解码过程完全相同。 In other words, atbash is a pair of identical functions -换句话说, atbash是一对相同的函数——

const atbash =
  cipher(n => 25 - n, n => 25 - n)

rot13 rot13

Next we look at our second cipher, rot13 -接下来我们看看我们的第二个密码, rot13 -

rot13(n) rot13(n) cipher密码
rot13(0) rot13(0) A → N A → N
rot13(1)腐烂13(1) B → O B→O
rot13(2)腐烂13(2) C → P C → P
rot13(23)腐烂13(23) X → K X → K
rot13(24)腐烂13(24) Y → L Y → L
rot13(25)腐烂13(25) Z → M Z → M

Rot13 is a Caesar shift of 13, so we can simply define it as Rot1313 的凯撒位移,所以我们可以简单地将其定义为

const rot13 =
  caesar(13)

caesar凯撒

And lastly Caesar allows us shift the character code by a specified amount -最后,Caesar 允许我们将字符代码移动指定的量 -

caesar(shift,n)凯撒(移位,n) cipher密码
caesar(-3,0)凯撒(-3,0) A → X A → X
caesar(-2,0)凯撒(-2,0) A → Y A → Y
caesar(-1,0)凯撒(-1,0) A → Z A → Z
caesar(0,0)凯撒(0,0) A → A一→一
caesar(1,0)凯撒(1,0) A → B甲→乙
caesar(2,0)凯撒(2,0) A → C A → C
caesar(3,0)凯撒(3,0) A → D A → D
caesar(-100,0)凯撒(-100,0) A → E A → E
caesar(100,0)凯撒(100,0) A → W A → W

We can implement caesar by parameterizing a cipher with a shift amount.我们可以通过使用shift量参数化cipher来实现caesar period is used to perform basic modular arithmetic and support any positive or negative shift amount - period用于执行基本的模运算并支持任何正或负移位量 -

const caesar = shift =>
  cipher
    ( n => period(26, n + shift) // plus shift for encode
    , n => period(26, n - shift) // minus shift for decode
    )

const period = (z, n) =>
  (z + n % z) % z

encode and decode编码和解码

The ciphers we defined operate on character codes but we don't expect the user to do handle that conversion manually.我们定义的密码对字符代码进行操作,但我们不希望用户手动处理该转换。 We will provide a simple encode function to work with -我们将提供一个简单的encode function 来使用 -

encode(atbash, "A")  // "Z"
encode(atbash, "B")  // "Y"
encode(atbash, "C")  // "Z"

encode(caesar(1), "A") // "B"
encode(caesar(2), "A") // "C"
encode(caesar(3), "A") // "D"

As well as the reversing decode function -以及反向decode function -

decode(atbash, "Z")  // "A"
decode(atbash, "Y")  // "B"
decode(atbash, "Z")  // "C"

decode(caesar(1), "B") // "A"
decode(caesar(2), "C") // "A"
decode(caesar(3), "D") // "A"

encode and decode accept a cipher, c , and an input string, s - encodedecode接受密码c和输入字符串s -

const encode = (c, s) =>
  transform(c.encode, s)

const decode = (c, s) =>
  transform(c.decode, s)

The transform procedure is the same whether you are encoding or decoding.无论您是编码还是解码, transform过程都是相同的。 The only things that changes is the alg orithm being used -唯一改变的是正在使用的alg -

const transform = (alg, s) =>
  Array
    .from(s, composeL(toCode, filter(alg), fromCode))
    .join("")

myCipher我的密码

Finally we write composeCipher which allows you to construct your own complex cipher from a sequence of ciphers.最后,我们编写composeCipher ,它允许您从一系列密码构建自己的复杂cipher The sequence of encoders runs from left-to-right using composeL .编码器序列使用composeL Naturally, the sequence of decoders runs in reverse from right-to-left using composeR -自然地,解码器序列使用composeR从右到左反向运行 -

const composeCipher = (...ciphers) =>
  cipher
    ( composeL(...ciphers.map(c => c.encode)) // encode
    , composeR(...ciphers.map(c => c.decode)) // decode
    )

const myCipher =
  composeCipher(rot13, atbash, caesar(3))
console.log(encode(myCipher, "DON'T CAUSE PANIC!"))
// MBC'W NPVXL APCHN!
console.log(decode(myCipher, "MBC'W NPVXL APCHN!"))
// DON'T CAUSE PANIC!

reusable functions可重用函数

Above we use composeL (left) and composeR (right) which are generic function composition procedures.上面我们使用composeL (左)和composeR (右),它们是通用的function 组合程序。 These allow us to building a single function out of a sequence of input functions.这些允许我们从一系列输入函数中构建单个 function。 You don't need to understand their implementation in order to use them -您无需了解它们的实现即可使用它们 -

// func.js

const composeL = (...fs) =>
  x => fs.reduce((r, f) => f(r), x)

const composeR = (...fs) =>
  x => fs.reduceRight((r, f) => f(r), x)

// ...

export { composeL, composeR, ... }

modules模块

Like we did with the func module above, you should bundle your very own cipher module to keep your code nice and tidy.就像我们对上面的func模块所做的那样,你应该捆绑你自己的cipher模块来保持你的代码整洁。 This also allows us to choose which parts of the module should be accessible to the user -这也允许我们选择用户应该可以访问模块的哪些部分 -

// cipher.js

import { composeL, composeR } from "./func.js"

const atbash = ...
const caesar = ...
const cipher = ...
const compose = ...
const decode = ...
const encode = ...
const fromCode = ...
const rot13 = ...
const toCode = ...
const transform = ...

export { atbash, caesar, cipher, compose, decode, encode, rot13 }

When we write our program, we only import the parts we need -当我们编写程序时,我们只导入我们需要的部分——

// main.js

import { compose, atbash, caesar, rot13 } from "./cipher.js"

const superSecret =
  compose(rot13, atbash, caesar(3))

console.log(encode(superSecret, "DON'T CAUSE PANIC!"))
console.log(decode(superSecret, "MBC'W NPVXL APCHN!"))
MBC'W NPVXL APCHN!
DON'T CAUSE PANIC!

demo演示

Expand the snippet below to verify the result in your own browser -展开下面的代码片段以在您自己的浏览器中验证结果 -

 // cipher.js const fromCode = n => String.fromCharCode(n) const toCode = s => s.toUpperCase().charCodeAt(0) const cipher = (encode, decode) => ({ encode, decode }) const atbash = cipher(n => 25 - n, n => 25 - n) const caesar = shift => cipher ( n => period(26, n + shift), n => period(26, n - shift) ) const rot13 = caesar(13) const filter = alg => n => n < 65 || n > 90? n: 65 + alg(n - 65) const period = (z, n) => (z + n % z) % z const transform = (f, s) => Array.from(s, composeL(toCode, filter(f), fromCode)).join("") const encode = (alg, s) => transform(alg.encode, s) const decode = (alg, s) => transform(alg.decode, s) const composeCipher = (...ciphers) => cipher ( composeL(...ciphers.map(c => c.encode)), composeR(...ciphers.map(c => c.decode)) ) // func.js const composeL = (...fs) => x => fs.reduce((r, f) => f(r), x) const composeR = (...fs) => x => fs.reduceRight((r, f) => f(r), x) // main.js const myCipher = composeCipher(rot13, atbash, caesar(3)) console.log(encode(myCipher, "DON'T CAUSE PANIC.")) console,log(decode(myCipher, "MBC'W NPVXL APCHN!"))

MBC'W NPVXL APCHN!
DON'T CAUSE PANIC!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Javascript中的XOR密码解密 - XOR cipher decryption in Javascript 只显示一半的 SVG - Show only half of SVG 使用 Javascript 计算字符串中只有字符(不是符号)的字符串长度 - Calculate the string length of only characters (not symbols) in the string using Javascript 谷歌地图只加载一半的部分,我已经在地图上使用了一些额外的javascript效果,但是只加载了一半 - google map only loads half of its portion,i have used some extra javascript for some effects on the map but its only loading half 验证字符串是否仅包含 javascript 中的某些字符 - Validate if a string contains only some characters in javascript JavaScript动画被卡住,只会显示最终结果 - JavaScript animation is stuck, and will show only end result JavaScript-仅验证数字/字母 - JavaScript - validating for only numeric/alphabet JavaScript Regex仅适用于第一个字符字母,第二个及以后可以是字母数字或特殊字符(连字符,逗号和空格) - JavaScript Regex for first character alphabet only, second and onwards can be alphanumeric or special characters (hyphen, comma and whitespace) 正则表达式只允许选择字母字符 - Regex to allow only select characters of alphabet JavaScript RegEx仅允许AlphaNumeric字符和一些特殊字符 - JavaScript RegEx to allow only AlphaNumeric Characters and some special characters
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM