【加密解密】单表加密(Javascript实现)

■单表加密(monoalphabetic)

替换加密是密码学中按规律将文字加密的一种方式。替换加密中可以用不同字母数为一单元,例如每一个或两个字母为一单元,然后再作加密。密文接收者解密时需用原加密方式解码才可取得原文本。由于拼音文字中字的组成为有限的字母,以英语为例只有26个字母,组成可能的单元数较少,因此使用替换式密码相对较为容易,而且亦可使用简单机械进行加密;相反,非拼音文字如中文则因单元数非常大难以使用一般加密方式,必需建立密码本,然后逐字替换。更何况某些非拼音文字中字字皆由不同大小的字根来组字,较难转换,因此使用替换式密码的示例比较少。

当以替换式密码与置换式密码相比较时,可以发现转位式密码只是改变明文中单元的位置,而单元本身没有转变;相反,替换式密码只是转换单元,但密文中单元的位置没有改变。

替换式密码亦有许多不同类型。如果每一个字母为一单元(或称元素)进行加密操作,就可以称之为“简易替换密码”( simple substitution cipher)或“单表加密”( monoalphabetic cipher),另又称为单字母替换加密;以数个字母为一单元则称为“多表加密”( polyalphabetic cipher)或“表格式加密”( polygraphic)。单表加密只可在一个单元中使用同一种替换加密,而多表加密则可在一个单元使用不同的加密方式,明文单元映射到密文上可以有好几种可能性,反之亦然。

简易替换加密是一种以特定方式改变字母表上字母顺序,并以此顺序书写的加密方式。这样一张改变了字母次序的字母表即为‘替换表’。替换表可以以偏移或逆转(分别为凯撒密码和阿特巴希密码(Atbash))或更复杂方式构造,此时称之为‘混合表’。传统上会先把一个关键词写在字母表最前面,再删去重复字母,这样就能得到一个混合表。

<SCRIPT language="JavaScript">
// encrypt/decrypt using a monoalphabetic cipher
function do_encrypt() {
    var key = document.cipher.key.value;
    // sanity check
    if ( key.length != 52 )    {
        window.alert("Key length is not 52 letters");
        return;
    }

    // get the message to encrypt
    var plaintext = document.cipher.plain.value;
    var ciphertext = "";
    // encrypt it
    for( var i = 0; i < plaintext.length; i ++ ) {
        // get this character as ascii
        var curchar = plaintext.charAt(i);
        // console.log(curchar);
        // is it a letter?
        if ( curchar >='A' && curchar <= 'Z' ) {
            // yes, encrypt convert 'a'->0, 'b'->1, ... 'z'->25
            var charpos = curchar.charCodeAt(0) - 65;
            // encrypt it
            ciphertext += key.charAt(charpos);
            // console.log(curchar + "," + key.charAt(charpos));
        } else if ( curchar >='a' && curchar <= 'z' ) {
            // yes, encrypt convert 'a'->0, 'b'->1, ... 'z'->25
            var charpos = curchar.charCodeAt(0) - 97 + 26;
            // encrypt it
            ciphertext += key.charAt(charpos);
            // console.log(curchar + "," + key.charAt(charpos));
        } else {
            // not a letter, leave it alone
            ciphertext += curchar;
        }
    } // for i

    document.cipher.enc.value = ciphertext;
}

function do_decrypt() {
    var key = document.cipher.key.value;
    // sanity check
    if ( key.length != 52 ) {
        window.alert("Key length is not 52 letters");
        return;
    }

    // get the message to encrypt
    var ciphertext = document.cipher.enc.value;
    var plaintext = "";
    // encrypt it
    for( var i=0; i<ciphertext.length; i++ ) {
        // get this character as ascii
        var curchar = ciphertext.charAt(i);
        // is it a letter?
        if ( curchar >='A' && curchar <= 'Z' ) {
            // yes, decrypt decrypt this letter
            var charpos = key.indexOf( curchar );
            // console.log(curchar + "," + charpos);
            // encrypt it
            plaintext += String.fromCharCode( charpos + 65 );
        } else if ( curchar >='a' && curchar <= 'z' ) {
            // yes, decrypt decrypt this letter
            var charpos = key.indexOf( curchar ) - 26;
            // encrypt it
            plaintext += String.fromCharCode( charpos + 97 );
            // console.log(curchar + "," + String.fromCharCode( charpos + 97 ));
        } else {
            // not a letter, leave it alone
            plaintext += curchar;
        }
    } // for i

    document.cipher.plain.value = plaintext;
}

// generate a random key
function gen_key() {
    var key = new Array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' );
    var i, j;

    for( i = 0; i < 26; i ++ ) {
        // swap this character with a random character generate a random position in the array
        j = Math.floor( Math.random() * 26 );
        // do the swap
        var t  = key[i];
        key[i] = key[j];
        key[j] = t;
    }
    for( i = 26; i < 52; i ++ ) {
        // swap this character with a random character generate a random position in the array
        j = Math.floor( Math.random() * 26 );
        // do the swap
        var t  = key[i];
        key[i] = key[j+26];
        key[j+26] = t;
    }

    // give it to the user
    document.cipher.key.value = key.join('');  
}
</script>
</head>
<body>
单表加密 monoalphabetic cipher.
<p>替换表:
<table border=1>
<tr><th>字母</th>
   <td>a</td><td>b</td><td>c</td><td>d</td><td>e</td><td>f</td><td>g</td>
   <td>h</td><td>i</td><td>j</td><td>k</td><td>l</td><td>m</td><td>n</td>
   <td>o</td><td>p</td><td>q</td><td>r</td><td>s</td><td>t</td><td>u</td>
   <td>v</td><td>w</td><td>x</td><td>y</td><td>z</td></tr>
<tr><th>替换</th>
   <td>y</td><td>n</td><td>l</td><td>k</td><td>x</td><td>b</td><td>s</td>
   <td>h</td><td>m</td><td>i</td><td>w</td><td>d</td><td>p</td><td>j</td>
   <td>r</td><td>o</td><td>q</td><td>v</td><td>f</td><td>e</td><td>a</td>
   <td>u</td><td>g</td><td>t</td><td>z</td><td>c</td></tr>
</table>
<p>
加密信息test,逐个查表替换为:exfe.
<p>
反之则为解密.
<p>
<hr>
<p>

<form name="cipher">
<table>
<tr><td>键值:</td><td><input type="text" name="key" size=50 value="ISYVKJRUXEDZQMCTPLOFNBWGAHisyvkjruxedzqmctplofnbwgah" readonly>&nbsp;<input type="button" value="生成随机键值" onClick="gen_key()"></td></tr>
<tr><td>明文:</td><td><input type="text" name="plain" size=50 value="This is a test."></td></tr>
<tr><td>密文:</td><td><input type="text" name="enc" size=50></td></tr>
</table>
<input type="button" value="加密" onClick="do_encrypt()">&nbsp;
<input type="button" value="解密" onClick="do_decrypt()">
</form>

 

转载于:https://my.oschina.net/dubenju/blog/833183

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值