JS字符串加密方式的探索,饼有点大。估计会变成连载...(ΩДΩ)
注意:本篇文章将的是对字符串的加密,不是对JS代码的加密。不过加密的方式或可以作为JS代码加密的思想(等后期研究JS代码加密的时候看看吧,先挖个坑)
很多场景中,我们都会将一些信息保存到用户本地。安全起见,肯定要为这些信息做加密处理。一般来说,这些信息是要再次获取使用的,所以不太适合使用那些不可逆的加密,而这篇文章主要讲一下那些JS中可逆的加密算法。
先从简单的说起来吧!
一、编码类加密
通过对字符串内容进行编码,来影响人们正常阅读,从而实现变相的加密,编码类有好多种,也是最容易被破解的一类
1. escape()
方法
该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . / 。其他所有的字符都会被转义序列替换。
例如:
escape('123 abc') ==> "123%20abc"
解码:通过 escape()
编码的字符串,可以使用unescape()
进行解码。
2. encodeURI()
方法和 encodeURIComponent()
方法:
encodeURI()
方法返回一个已编码的 URI。如果将编码结果传递给 decodeURI()
,则将返回初始的字符串。encodeURI()
不对下列字符进行编码:“:”、“/”、“;”和“?”。请使用encodeURIComponent()
对这些字符进行编码。
例如:
`
encodeURI("https://www.lingmx.com/哈哈哈") ==> https://www.lingmx.com/%E5%93%88%E5%93%88%E5%93%88"
encodeURIComponent("https://www.lingmx.com/哈哈哈") ==>"https%3A%2F%2Fwww.lingmx.com%2F%E5%93%88%E5%93%88%E5%93%88"
`
解码:通过 encodeURI()
编码的字符串,可以使用decodeURI()
进行解码。通过encodeURIComponent()
编码的字符串,可以使用decodeURIComponent()
进行解码。
3. btoa()
方法
改方法用于创建一个 base-64 编码的字符串,使用 "A-Z", "a-z", "0-9", "+", "/" 和 "=" 字符来编码字符串
例如:
btoa("LingMX") ==> "TGluZ01Y"
解码:通过btoa()
方法编码,可以使用atob()
方法进行解码。
二、 凯撒密码(Caesar cipher)
明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。
下面说下实现的方法(如有更简便的方法可以回复我o( ̄︶ ̄)o):
// 加密:
// 字符集
let dic = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";
// 凯撒密码 加密
function enc(str, k) { // str要加密的字符串 k位移量
let str2 = "";
for (let i = 0; i < str.length; i++) {
let index = dic.indexOf(str[i]) + k; // 获取位移后的下标
index = index >= dic.length ? index % dic.length : index; // 判断是否超出字符集,超出则取模
str2 += dic[index]; // 拼接加密后的字符串
}
return str2
}
//调用:
enc("LingMX",7) // ==> "SpunT4"
//凯撒密码 解密:
function dec(str, k) { // str要加密的字符串 k位移量
let str2 = "";
for (let i = 0; i < str.length; i++) {
let index = dic.indexOf(str[i]) - k; // 获取位移后的下标
index = index < 0 ? dic.length + index : index; // 判断是否超出字符集,超出则从最后一位开始
str2 += dic[index]; // 拼接加密后的字符串
}
return str2
}
//调用:
dec("SpunT4",7) // ==> "LingMX"
三、维吉尼亚密码(凯撒密码Plus)
维吉尼亚密码相比之下提升了安全性,维吉尼亚密码是由一些偏移量不同的恺撒密码组成(凯撒密码Plus没得跑),通常是一个单词。
下面是实现方式:
// 字符集
let dic = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";
// 维尔尼亚密码 加密
function enc(str, key) { // str 要加密的字符串 key 秘钥
let str2 = "";
for (let i = 0; i < str.length; i++) {
let index = dic.indexOf(str[i]) + dic.indexOf(key[i % key.length]); // 获取位移后的下标
index = index >= dic.length ? index % dic.length : index; // 判断是否超出字符集,超出则从第一位开始
str2 += dic[index]; // 拼接加密后的字符串
}
return str2
}
// 调用
enc("LingMX", "BestMan") // ==> "=mFzlX"
// 维尔尼亚密码 解密
function dec(str, key) { // str 要加密的字符串 key 秘钥
let str2 = "";
for (let i = 0; i < str.length; i++) {
let index = dic.indexOf(str[i]) - dic.indexOf(key[i % key.length]); // 获取位移后的下标
index = index < 0 ? dic.length + index : index; // 判断是否超出字符集,超出则从最后一位开始
str2 += dic[index]; // 拼接加密后的字符串
}
return str2
}
// 调用
dec("=mFzlX", "BestMan") // ==> "LingMX"
本篇文章就到此结束了,后面的加密方法是我自己写的。如果有更好的方法,可以留言告诉我,或者发邮件到我邮箱:l@lingmx.com
。大家相互学习~
参考文章:
【密码学发展简史】