这两天一直没有更新任何的文章,是因为我一直在想这个加密算法应该怎么写,这几天想了很多,终于写了一个自己觉得还比较完备的加密算法,我们没有写之前首先要明白,做一个加密的算法是一件逻辑性要相对强一点,也就是说考虑的要全面一点,这样才可以保证的是加密之后的密码不那么容易的被破解掉。
这个加密的算法名字就叫做CL加密吧,我的名字是ClearLove!
关于加密我之前也写过相关的文章,这里就不做赘述,想看的可以直接去看一下:
所谓的加密,其实就是给原始密码穿件衣服,让黑客第一眼看不出来内核到底是什么!这个我在网上看到一个段子形容的很好:
小的时候,两个人想上课聊天,但是又怕被抓到,这个时候两个人就约定俗成一种规则,1代表您好,2代表吃饭...就这样,纸条上面永远只有阿拉伯数字,那么即使老师拿到了,也是没用的,因为他不知道什么意思,其实这就是加密最初始的思路。还有以前的电报原理也是这样的等等很多现实生活中的例子!
我的思路要求是这样的:
用户输入数字和字母和符号对应出不同的映射表
通过运算法则以后得到一个加密后的密码
不可逆的
但是每次加密的结果都是一样的,这就可以避免使用GUID或者是时间戳进行加密了
以上是简单的要求,那么对应的解决思路是这样的:
第一步:
使用正则表达式将数字、字母、符号分开
第二步:
将数字最后一个数组的数字进行二进制转换,向右移动一位,再转为十进制
第三步:
将字母根据映射表一一对应出
第四步:
将数据每一个部分组合起来
需要避免的情况是:
还要保证的是顺序不同的时候生成的密码是不一样的
那么就要保证的是原始密码顺序不可以变
但是如果完全是原始密码的话,也是不行的,那么就需要将原始密码某一位删除,这样可以保证即使看到了原始密码也一定不是用户输入的密码
要保证的是不同的密码不可能生成同一个加密后的密码
那么就要用到用户原始的部分密码,然后特别的位置进行加密
效果预览:
ps:这里我没有做任何的美化,喜欢或者感兴趣的可以自己美化一下。
我们今天简单的实现这个:
H5源码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CL加密</title>
<script src="css/layui/lay/dest/layui.all.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery-1.11.2.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/CL_ency.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="css/layui/css/layui.css"/>
</head>
<style type="text/css">
body{text-align: center;margin-top: 1rem;}
div{background-color: #AAAAAA;height: 20rem;width: 40rem;margin-top: 1rem;margin-left: 30%;}
input{font-family: "agency fb";font-size: 2rem;margin-top: 1rem;}
span{font-family: "agency fb";font-size: 2rem;margin-top: 1rem;}
</style>
<body>
<div id="encry">
<span>输入密码:</span><input type="password" id="psd" value="" />
<input type="button" name="" id="_CLencry" value="CL加密" οnclick="ency()"/><br />
<span id="relult"></span>
</div>
</body>
<script type="text/javascript">
/* 加载欢迎的提示 */
/* $(function(){
layer.msg("欢迎使用CL加密");
}) */
function ency(){
var pssd = $("#psd").val();
var j = _CLencrypt(pssd);
$("#relult").empty();
$("#relult").append("加密后的数据是:"+j);
}
</script>
</html>
js源码:
/*
aim : 加密
author : ClearLove
Date : 2018-06-25
Ps : 不经允许,不得擅自使用转载!
*/
function _CLencrypt(psd){
var reg = new RegExp(/[A-Za-z].*[0-9]|[0-9].*[A-Za-z]/);
if (psd == null || psd.length <8 || psd.length >14) {
alert("密码数在8-14之间");
return false;
}else{
if(!reg.test(psd)){
alert("密码至少包含字母和数字或者符号");
return false;
}
else{
/* 使用正则取出数字 */
var usernum = psd.match(/[1-9][0-9]*/g);
var numlast;//数组的最后一位
var decimalnum;//进行二进制转换,然后向右移动一位,最后转为十进制的结果
var majuscule;//最后一位大写字母
var minuscule;//最后一位小写字母
var alphabet;//剩余的字母除去最后一位的
var allnum;//密码全部的数字
var exceptlast;//去掉字符的最后一位
var allcharts;//原始密码去掉最后一位的值
/* 将数组的最后一组数字拿到 */
numlast = usernum[usernum.length-1];
/* 将拿到的数字进行二进制转换之后在向右移动一位,最后转为十进制得到结果 */
decimalnum = numlast >>> 1;
/* 将里面的字母拿到 */
alphabet = psd.replace(/[0-9]/ig,"");
/* 将字符串的最后一位去掉 */
exceptlast = alphabet.substr(0,alphabet.length - 1);
/* 除最后一位之外的字符串*/
/* 将数据的字符串全部显示为大写 */
var uppsd = psd.toUpperCase();
allcharts = uppsd.substr(0,uppsd.length - 1);
/* 将里面的数字拿到 */
allnum = psd.replace(/[^0-9]/ig,"");
var capital = psd.match(/[a-z][A-Z]*/g);
if(capital == "" || capital == null){
_MBAmapmin(0);
}
else{
/* 对字母进行一一映射 */
/* 将小写字母的最后一位拿到 */
minuscule = capital[capital.length-1];
_MBAmapmin(minuscule);
}
/* 将大写字母的最后一位拿到 */
var lowercase = psd.match(/[A-Z][a-z]*/g);
if(lowercase == "" || lowercase == null){
_MBAmapmaj(0);
}
else{
/* 对字母进行一一映射 */
majuscule = lowercase[lowercase.length-1];
_MBAmapmaj(majuscule);
}
/* 将最后的每一部分拼接出来 */
var algorithm = Ascii_minuscule + decimalnum + allcharts + Ascii_majuscule;
return algorithm;
}
}
}
/* 字母映射表 对应的是小写字母的Ascii码表中的二进制*/
var Ascii_minuscule;//小写字母对应的Ascii二进制数据
var Ascii_majuscule;//大写字母对应的Ascii二进制数据
function _MBAmapmin(minuscule){
switch(minuscule){
case 'a':
Ascii_minuscule = "01100001";
break;
case 'b':
Ascii_minuscule = "01100010";
break;
case 'c':
Ascii_minuscule = "01100011";
break;
case 'd':
Ascii_minuscule = "01100100";
break;
case 'e':
Ascii_minuscule = "01100101";
break;
case 'f':
Ascii_minuscule = "01100110";
break;
case 'g':
Ascii_minuscule = "01100111";
break;
case 'h':
Ascii_minuscule = "01101000";
break;
case 'i':
Ascii_minuscule = "01101001";
break;
case 'j':
Ascii_minuscule = "01101010";
break;
case 'k':
Ascii_minuscule = "01101011";
break;
case 'l':
Ascii_minuscule = "01101100";
break;
case 'm':
Ascii_minuscule = "01101101";
break;
case 'n':
Ascii_minuscule = "01101110";
break;
case 'o':
Ascii_minuscule = "01101111";
break;
case 'p':
Ascii_minuscule = "01110000";
break;
case 'q':
Ascii_minuscule = "01110001";
break;
case 'r':
Ascii_minuscule = "01110010";
break;
case 's':
Ascii_minuscule = "01110011";
break;
case 't':
Ascii_minuscule = "01110100";
break;
case 'u':
Ascii_minuscule = "01110101";
break;
case 'v':
Ascii_minuscule = "01110110";
break;
case 'w':
Ascii_minuscule = "01110111";
break;
case 'x':
Ascii_minuscule = "01111000";
break;
case 'y':
Ascii_minuscule = "01111001";
break;
case 'z':
Ascii_minuscule = "01111010";
break;
default:
Ascii_minuscule = "00000000"
}
}
/* 字母映射表 对应的是大写字母的Ascii码表中的二进制*/
function _MBAmapmaj(majuscule){
switch(majuscule){
case 'A':
Ascii_majuscule = "01000001";
break;
case 'B':
Ascii_majuscule = "01000010";
break;
case 'C':
Ascii_majuscule = "01000011";
break;
case 'D':
Ascii_majuscule = "01000100";
break;
case 'E':
Ascii_majuscule = "01000101";
break;
case 'F':
Ascii_majuscule = "01000110";
break;
case 'G':
Ascii_majuscule = "01000111";
break;
case 'H':
Ascii_majuscule = "01001000";
break;
case 'I':
Ascii_majuscule = "01001001";
break;
case 'J':
Ascii_majuscule = "01001010";
break;
case 'K':
Ascii_majuscule = "01001011";
break;
case 'L':
Ascii_majuscule = "01001100";
break;
case 'M':
Ascii_majuscule = "01001101";
break;
case 'N':
Ascii_majuscule = "01001110";
break;
case 'O':
Ascii_majuscule = "01001111";
break;
case 'P':
Ascii_majuscule = "01010000";
break;
case 'Q':
Ascii_majuscule = "01010001";
break;
case 'R':
Ascii_majuscule = "01010010";
break;
case 'S':
Ascii_majuscule = "01010011";
break;
case 'T':
Ascii_majuscule = "01010100";
break;
case 'U':
Ascii_majuscule = "01010101";
break;
case 'V':
Ascii_majuscule = "01010110";
break;
case 'W':
Ascii_majuscule = "01010111";
break;
case 'X':
Ascii_majuscule = "01011000";
break;
case 'Y':
Ascii_majuscule = "01011001";
break;
case 'Z':
Ascii_majuscule = "01011010";
break;
default:
Ascii_majuscule = "00000000"
}
}
ps1:这里的字母对照表使用的是Ascii码表,使用这个的原因有以下几个:
第一:他是没有重复的
第二:他是二进制数据
ps2:这里看完js的人应该可以看出问题,就是我没有删除密码里面的最后一位数字,原因是这样的,我对数字的处理是先将数字拿到,然后将拿到的数字的最后一位进行二进制运算,之后将运算的结果向右移动一位,最后将移动后的数据转为十进制得到的,那么这个时候我们是可以破解的,但是如果用户的密码刚好是String类型的加上数字的,那么这个时候我拼接的字符串那里是十进制数据加上原始数字密码,这个时候是可以知道用户的密码是从第几位开始的,因为你可以看到最后一位,然后你将最后一位的数据按照我的预算规则预算出一个结果,然后去掉拼接的字符串就是原始的密码开始的位置,这样做的目的是给以后写解密留后路!
ps3:为什么说这个是不可逆的呢?因为我将所有的密码全部转为大写的,这样即使拿到了密码,也是不知道原始的第几位是小写,但是这样写有一定的风险,就是如果两个密码完全一样, 只有大小写不一样的时候,那么生成的密码可能是一样的。
最后,这个算法虽然我想了一下,但是漏洞还是很多的,只是说小的公司要求不高的,但是有需要加密的,是可以借鉴的,毕竟小生能力有限,不过不是说做不出来完备的,只是没有那么多的精力,其实如果有兴趣的话,完全可以将密码的每一位都取出来,然后每一位都进行自己定义的规则码进行加密,这样被破解的可能性就相对小一点,甚至说只要规则不被破解,永远不会被破解!
这里面用到了正则表达式,附带一张正则表达式的规则图: