全网最强密码规则效验(java后台版和javascript版)
最强密码规则效验:(java后台版和javascript版)
需求如下:
- (一)口令至少由8位及以上大小写字母、数字及特殊字符等混合、随机组成(至少包括数字、小写字母、大写字母和特殊符号中的三种)。
同时严禁在口令中包含以下情况:
连续数字或重复数字:如“678”或“AAA”等; 英文单词或拼音:如“oper”或“admin”等;
含有与账号名、主机名、系统名、厂商名相同或相似的字符串;
含有与局房、人员姓名、生日、证件号码、电话号码、手机号码及门牌号码等相同或相似的字符串;
位于键盘相邻位置的字符超过2位,例如“2wsx@WSX”或“2we4@WE$”等;
使用系统或应用的默认口令,例如“ftp@ftp.net”等; 属于弱口令库中的常见口令。
(二)应以HASH或者加密技术保存口令,不得以明文方式保存或者传输;
(三)账号使用者至少每90天对口令更换一次,5次以内不得设置相同的口令。修改口令时,须保留口令修改记录以备审计(具体格式参见附件1);
(四)重要系统应采用短信动态口令、证书等强认证登录方式。
(五)由于员工离职等原因,原账号不能删除或者需要重新赋予另一个人时,应修改相应账号的口令。
前端版:
function checkProv(val) {
var pattern = /^[1-9][0-9]/;
var provs = {11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门"};
if(pattern.test(val)) {
if(provs[val]) {
return true;
}
}
return false;
}
function checkDate(val) {
var pattern = /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/;
if(pattern.test(val)) {
var year = val.substring(0, 4);
var month = val.substring(4, 6);
var date = val.substring(6, 8);
var date2 = new Date(year+"-"+month+"-"+date);
if(date2 && date2.getMonth() == (parseInt(month) - 1)) {
return true;
}
}
return false;
}
function checkCode(val) {
var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
var factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ];
var parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ];
var code = val.substring(17);
if(p.test(val)) {
var sum = 0;
for(var i=0;i<17;i++) {
sum += val[i]*factor[i];
}
if(parity[sum % 11] == code.toUpperCase()) {
return true;
}
}
return false;
}
//检测密码是否是身份证
function checkID(val) {
if (checkCode(val)) {
var date = val.substring(6, 14);
if (checkDate(date)) {
if (checkProv(val.substring(0, 2))) {
return true;
}
}
}
return false;
}
//密码不得包含键盘上任意连续的三个字符或shift转换字符
function validateKey(str) {
//定义横向穷举
var keyCode = [
["`~·", "1=", "2@@", "3#", "4$¥", "5%", "6^……", "7&", "8*", "9((", "0))", "-_", "=+"],
[" ","qQ", "wW", "eE", "rR", "tT", "yY", "uU", "iI", "oO", "pP", "[{【", "]}】", "\\|、"],
[" ","aA", "sS", "dD", "fF", "gG", "hH", "jJ", "kK", "lL", ";:", "\'\"’“"],
[" ","zZ", "xX", "cC", "vV", "bB", "nN", "mM", ",《<", ".>》", "/??"]
];
//找出给出的字符串,每个字符,在坐标系中的位置。
var c = str.split("");
console.log(c)
var x = new Array();
var y = new Array();
for (var i = 0; i < c.length; i++) {
var temp = c[i];
toHere:
for (var j = 0; j < keyCode.length; j++) {
for (var k = 0; k < keyCode[j].length; k++) {
var jk = keyCode[j][k];
if (jk.indexOf(temp)!=-1) {
x.push(j);
y.push(k);
break toHere;
}
}
}
}
var flag = false;
for (var i = 0; i < x.length - 2; i++) {
// 如果X一致,那么就是在一排
if (x[i] == x[i + 1] && x[i + 1] == x[i + 2]) {//四者在同一行上
if (y[i] > y[i + 2]) {
if (y[i] - 1 == y[i + 1] && y[i] - 2 == y[i + 2]) {
flag = true;
break;
}
} else {
if (y[i] + 1 == y[i + 1] && y[i] + 2 == y[i + 2]) {
flag = true;
break;
}
}
} else if (x[i] != x[i + 1]
&& x[i + 1] != x[i + 2]
&& x[i] != x[i + 2]
) {//四者均不在同一行上,但是如果y相同,说明是一列
if (y[i] == y[i + 1] && y[i + 1] == y[i + 2]) {
flag = true;
break;
}
}
}
return flag;
}
//不能相同字符(如111、aaa)连续3位或3位以上
function checkSame(str) {
var re = /(\w)*(\w)\2{2}(\w)*/g;
if(re.test(str)){
return true;
}else{
return false;
}
}
//不能连续字符(如123、abc)连续3位或3位以上
function checkRepeat(str){
var arr = str.split('');
var flag = false;
for (var i = 1; i < arr.length-1; i++) {
var firstIndex = arr[i-1].charCodeAt();
var secondIndex = arr[i].charCodeAt();
var thirdIndex = arr[i+1].charCodeAt();
thirdIndex - secondIndex == 1;
secondIndex - firstIndex==1;
if((thirdIndex - secondIndex == 1)&&(secondIndex - firstIndex==1)){
flag = true;
}
}
if(!flag){
return flag;
}
return flag;
}
后台:
```java
package com.cmcc.system.util;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
public class CheckPassword {
/**
* 三个或者三个以上相同
* @return
*/
public static String check3(String pwd) {
String regx = "^.*(.)\\1{2}.*$";
Matcher m = null;
Pattern p = null;
p = Pattern.compile(regx);
m = p.matcher(pwd);
if(m.matches()) {
return "包含三个或者三个以上相同";
}else {
return "ok";
}
}
/**
* 验证生日 、身份证
* @return
*/
public static String checkBirthday(String pwd) {
String birthday = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)";
Pattern pattern = Pattern.compile(birthday);
Matcher matcher = pattern.matcher(pwd);
if (matcher.find()) {
return "包含生日或者身份证";
}else {
return "ok";
}
}
/**
* 密码规则
* @return
*/
public static String checkp(String pwd) {
String str = "^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\\W_!@#$%^&*`~()-+=]+$)(?![0-9\\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\\W_!@#$%^&*`~()-+=]{8,30}$";
if (!pwd.matches(str)) {
return "口令至少由8位及以上大小写字母、数字及特殊字符等混合、随机组成(至少包括数字、小写字母、大写字母和特殊符号中的三种";
}else {
return "ok";
}
}
/**
* 验证密码
* @param pwd
* @return
*/
public static String checkPwd(String pwd) {
//密码规则
String checkp = checkp(pwd);
//键盘上连续3位或者以上
String rsThree = validateKey(pwd);
String repeat = checkRepeat(pwd);
//包含生日
String checkBirthday = checkBirthday(pwd);
//三个或者三个以上相同
String check3 = check3(pwd);
//包含手机号
String checkMobile = checkMobile(pwd);
//包含固定电话
String checkPhone = checkPhone(pwd);
if (!"ok".equals(checkp)) {
return checkp;
}else if(!"ok".equals(rsThree)) {
return rsThree;
}else if(!"ok".equals(repeat)) {
return repeat;
}else if(!"ok".equals(checkBirthday)) {
return checkBirthday;
}else if(!"ok".equals(check3)) {
return check3;
}else if(!"ok".equals(checkMobile)) {
return checkMobile;
}else if(!"ok".equals(checkPhone)) {
return checkPhone;
}else {
return "true";
}
}
/**
* 包含手机号
* @param sParam
* @return
*/
public static String checkMobile(String sParam){
if(sParam.length()<=0)
return "";
Pattern pattern = Pattern.compile("(1|861)(3|4|5|6||7|8|9)\\d{9}$*");
Matcher matcher = pattern.matcher(sParam);
StringBuffer bf = new StringBuffer();
while (matcher.find()) {
bf.append(matcher.group()).append(",");
}
int len = bf.length();
if (len > 0) {
bf.deleteCharAt(len - 1);
}
if (StringUtils.isNotBlank(bf.toString())) {
return "包含手机号";
}else {
return "ok";
}
}
/**
* 包含固定电话
* @param content
* @return
*/
public static String checkPhone(String content) {
List<String> list = new ArrayList<>();
Pattern p = Pattern.compile("\\d{3}-\\d{8}|\\d{4}-\\d{6}|\\d{7}|\\d{8}");
Matcher matcher = p.matcher(content);
while (matcher.find()) {
String n = matcher.group(0).toString();
list.add(n);
}
if (!list.isEmpty()) {
return "包含固定电话";
}else {
return "ok";
}
}
//密码不得包含键盘上任意连续的三个字符或shift转换字符
public static String validateKey(String str) {
//定义横向穷举
String[][] keyCode = {
{"`~·", "1=", "2@@", "3#", "4$¥", "5%", "6^……", "7&", "8*", "9((", "0))", "-_", "=+"},
{" ","qQ", "wW", "eE", "rR", "tT", "yY", "uU", "iI", "oO", "pP", "[{【", "]}】", "\\|、"},
{" ","aA", "sS", "dD", "fF", "gG", "hH", "jJ", "kK", "lL", ";:", "\'\"’“"},
{" ","zZ", "xX", "cC", "vV", "bB", "nN", "mM", ",《<", ".>》", "/??"}
};
//找出给出的字符串,每个字符,在坐标系中的位置。
char[] c = str.toCharArray();
List<Integer> x = new ArrayList<Integer>();
List<Integer> y = new ArrayList<Integer>();
for (int i = 0; i < c.length; i++) {
char temp = c[i];
toHere:
for (int j = 0; j < keyCode.length; j++) {
for (int k = 0; k < keyCode[j].length; k++) {
String jk = keyCode[j][k];
if (jk.contains(String.valueOf(temp))) {
x.add(j);
y.add(k);
break toHere;
}
}
}
}
boolean flag = false;
for (int i = 0; i < x.size() - 2; i++) {
// 如果X一致,那么就是在一排
if (x.get(i) == x.get(i + 1) && x.get(i + 1) == x.get(i + 2) ) {//四者在同一行上
if (y.get(i) > y.get(i + 2)) {
if (y.get(i) - 1 == y.get(i + 1) && y.get(i) - 2 == y.get(i + 2) ) {
flag = true;
break;
}
} else {
if (y.get(i) + 1 == y.get(i + 1) && y.get(i) + 2 == y.get(i + 2) ) {
flag = true;
break;
}
}
} else if (x.get(i) != x.get(i + 1)
&& x.get(i + 1) != x.get(i + 2)
&& x.get(i) != x.get(i + 2)
) {//四者均不在同一行上,但是如果y相同,说明是一列
if (y.get(i) == y.get(i + 1) && y.get(i + 1) == y.get(i + 2)) {
flag = true;
break;
}
}
}
if (flag) {
return "不能连续三个或者三个以上字符";
}else {
return "ok";
}
}
//转码
public static int getUnicode(char c){
String returnUniCode=null;
returnUniCode=String.valueOf((int)c);
return Integer.parseInt(returnUniCode);
}
//不能连续字符(如123、abc)连续3位或3位以上
public static String checkRepeat(String str){
String[] arr = str.split("");
boolean flag = false;
for (int i = 1; i < arr.length-1; i++) {
int firstIndex = getUnicode(arr[i-1].charAt(0));
int secondIndex = getUnicode(arr[i].charAt(0));
int thirdIndex = getUnicode (arr[i+1].charAt(0));
if((thirdIndex - secondIndex == 1)&&(secondIndex - firstIndex==1)){
flag = true;
}
}
if (flag) {
return "不能连续3字母";
}else {
return "ok";
}
}