CheckStrength.java 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package com.sooka.common.utils;
  2. /**
  3. * @author limeng
  4. * @date 2021年07月26日 16:35
  5. */
  6. public class CheckStrength {
  7. public enum LEVEL {
  8. EASY, MIDIUM, STRONG, VERY_STRONG, EXTREMELY_STRONG
  9. }
  10. /**
  11. * NUM 数字
  12. * SMALL_LETTER 小写字母
  13. * CAPITAL_LETTER 大写字母
  14. * OTHER_CHAR 特殊字符
  15. */
  16. private static final int NUM = 1;
  17. private static final int SMALL_LETTER = 2;
  18. private static final int CAPITAL_LETTER = 3;
  19. private static final int OTHER_CHAR = 4;
  20. /**
  21. * 简单的密码字典
  22. */
  23. private final static String[] DICTIONARY = {"password", "abc123", "iloveyou", "adobe123", "123123", "sunshine",
  24. "1314520", "a1b2c3", "123qwe","111111","123456", "aaa111", "qweasd", "admin", "passwd"};
  25. /**
  26. *检查字符类型,包括num、大写字母、小写字母和其他字符。
  27. *
  28. * @param c
  29. * @return
  30. */
  31. private static int checkCharacterType(char c) {
  32. if (c >= 48 && c <= 57) {
  33. return NUM;
  34. }
  35. if (c >= 65 && c <= 90) {
  36. return CAPITAL_LETTER;
  37. }
  38. if (c >= 97 && c <= 122) {
  39. return SMALL_LETTER;
  40. }
  41. return OTHER_CHAR;
  42. }
  43. /**
  44. * 按不同类型计算密码的数量
  45. *
  46. * @param passwd
  47. * @param type
  48. * @return
  49. */
  50. private static int countLetter(String passwd, int type) {
  51. int count = 0;
  52. if (null != passwd && passwd.length() > 0) {
  53. for (char c : passwd.toCharArray()) {
  54. if (checkCharacterType(c) == type) {
  55. count++;
  56. }
  57. }
  58. }
  59. return count;
  60. }
  61. /**
  62. * 检查密码的强度
  63. *
  64. * @param passwd
  65. * @return strength level
  66. */
  67. public static int checkPasswordStrength(String passwd) {
  68. if (StringUtils.equalsNull(passwd)) {
  69. throw new IllegalArgumentException("password is empty");
  70. }
  71. int len = passwd.length();
  72. int level = 0;
  73. // 增加点
  74. //判断密码是否含有数字有level++
  75. if (countLetter(passwd, NUM) > 0) {
  76. level++;
  77. }
  78. //判断密码是否含有小写字母有level++
  79. if (countLetter(passwd, SMALL_LETTER) > 0) {
  80. level++;
  81. }
  82. //判断密码是否还有大写字母有level++
  83. if (len > 4 && countLetter(passwd, CAPITAL_LETTER) > 0) {
  84. level++;
  85. }
  86. //判断密码是否还有特殊字符有level++
  87. if (len > 6 && countLetter(passwd, OTHER_CHAR) > 0) {
  88. level++;
  89. }
  90. //密码长度大于4并且2种类型组合......(不一一概述)
  91. if (len > 4 && countLetter(passwd, NUM) > 0 && countLetter(passwd, SMALL_LETTER) > 0
  92. || countLetter(passwd, NUM) > 0 && countLetter(passwd, CAPITAL_LETTER) > 0
  93. || countLetter(passwd, NUM) > 0 && countLetter(passwd, OTHER_CHAR) > 0
  94. || countLetter(passwd, SMALL_LETTER) > 0 && countLetter(passwd, CAPITAL_LETTER) > 0
  95. || countLetter(passwd, SMALL_LETTER) > 0 && countLetter(passwd, OTHER_CHAR) > 0
  96. || countLetter(passwd, CAPITAL_LETTER) > 0 && countLetter(passwd, OTHER_CHAR) > 0) {
  97. level++;
  98. }
  99. //密码长度大于6并且3中类型组合......(不一一概述)
  100. if (len > 6 && countLetter(passwd, NUM) > 0 && countLetter(passwd, SMALL_LETTER) > 0
  101. && countLetter(passwd, CAPITAL_LETTER) > 0 || countLetter(passwd, NUM) > 0
  102. && countLetter(passwd, SMALL_LETTER) > 0 && countLetter(passwd, OTHER_CHAR) > 0
  103. || countLetter(passwd, NUM) > 0 && countLetter(passwd, CAPITAL_LETTER) > 0
  104. && countLetter(passwd, OTHER_CHAR) > 0 || countLetter(passwd, SMALL_LETTER) > 0
  105. && countLetter(passwd, CAPITAL_LETTER) > 0 && countLetter(passwd, OTHER_CHAR) > 0) {
  106. level++;
  107. }
  108. //密码长度大于8并且4种类型组合......(不一一概述)
  109. if (len > 8 && countLetter(passwd, NUM) > 0 && countLetter(passwd, SMALL_LETTER) > 0
  110. && countLetter(passwd, CAPITAL_LETTER) > 0 && countLetter(passwd, OTHER_CHAR) > 0) {
  111. level++;
  112. }
  113. //密码长度大于6并且2种类型组合每种类型长度大于等于3或者2......(不一一概述)
  114. if (len > 6 && countLetter(passwd, NUM) >= 3 && countLetter(passwd, SMALL_LETTER) >= 3
  115. || countLetter(passwd, NUM) >= 3 && countLetter(passwd, CAPITAL_LETTER) >= 3
  116. || countLetter(passwd, NUM) >= 3 && countLetter(passwd, OTHER_CHAR) >= 2
  117. || countLetter(passwd, SMALL_LETTER) >= 3 && countLetter(passwd, CAPITAL_LETTER) >= 3
  118. || countLetter(passwd, SMALL_LETTER) >= 3 && countLetter(passwd, OTHER_CHAR) >= 2
  119. || countLetter(passwd, CAPITAL_LETTER) >= 3 && countLetter(passwd, OTHER_CHAR) >= 2) {
  120. level++;
  121. }
  122. //密码长度大于8并且3种类型组合每种类型长度大于等于3或者2......(不一一概述)
  123. if (len > 8 && countLetter(passwd, NUM) >= 2 && countLetter(passwd, SMALL_LETTER) >= 2
  124. && countLetter(passwd, CAPITAL_LETTER) >= 2 || countLetter(passwd, NUM) >= 2
  125. && countLetter(passwd, SMALL_LETTER) >= 2 && countLetter(passwd, OTHER_CHAR) >= 2
  126. || countLetter(passwd, NUM) >= 2 && countLetter(passwd, CAPITAL_LETTER) >= 2
  127. && countLetter(passwd, OTHER_CHAR) >= 2 || countLetter(passwd, SMALL_LETTER) >= 2
  128. && countLetter(passwd, CAPITAL_LETTER) >= 2 && countLetter(passwd, OTHER_CHAR) >= 2) {
  129. level++;
  130. }
  131. //密码长度大于10并且4种类型组合每种类型长度大于等于2......(不一一概述)
  132. if (len > 10 && countLetter(passwd, NUM) >= 2 && countLetter(passwd, SMALL_LETTER) >= 2
  133. && countLetter(passwd, CAPITAL_LETTER) >= 2 && countLetter(passwd, OTHER_CHAR) >= 2) {
  134. level++;
  135. }
  136. //特殊字符>=3 level++;
  137. if (countLetter(passwd, OTHER_CHAR) >= 3) {
  138. level++;
  139. }
  140. //特殊字符>=6 level++;
  141. if (countLetter(passwd, OTHER_CHAR) >= 6) {
  142. level++;
  143. }
  144. //长度>12 >16 level++
  145. if (len > 12) {
  146. level++;
  147. if (len >= 16) {
  148. level++;
  149. }
  150. }
  151. // 减少点
  152. if ("abcdefghijklmnopqrstuvwxyz".indexOf(passwd) > 0 || "ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(passwd) > 0) {
  153. level--;
  154. }
  155. if ("qwertyuiop".indexOf(passwd) > 0 || "asdfghjkl".indexOf(passwd) > 0 || "zxcvbnm".indexOf(passwd) > 0) {
  156. level--;
  157. }
  158. if (StringUtils.isNumeric(passwd) && ("01234567890".indexOf(passwd) > 0 || "09876543210".indexOf(passwd) > 0)) {
  159. level--;
  160. }
  161. if (countLetter(passwd, NUM) == len || countLetter(passwd, SMALL_LETTER) == len
  162. || countLetter(passwd, CAPITAL_LETTER) == len) {
  163. level--;
  164. }
  165. if (len % 2 == 0) { // aaabbb
  166. String part1 = passwd.substring(0, len / 2);
  167. String part2 = passwd.substring(len / 2);
  168. if (part1.equals(part2)) {
  169. level--;
  170. }
  171. if (StringUtils.isCharEqual(part1) && StringUtils.isCharEqual(part2)) {
  172. level--;
  173. }
  174. }
  175. if (len % 3 == 0) { // ababab
  176. String part1 = passwd.substring(0, len / 3);
  177. String part2 = passwd.substring(len / 3, len / 3 * 2);
  178. String part3 = passwd.substring(len / 3 * 2);
  179. if (part1.equals(part2) && part2.equals(part3)) {
  180. level--;
  181. }
  182. }
  183. if (StringUtils.isNumeric(passwd) && len >= 6) { // 19881010 or 881010
  184. int year = 0;
  185. if (len == 8 || len == 6) {
  186. year = Integer.parseInt(passwd.substring(0, len - 4));
  187. }
  188. int size = StringUtils.sizeOfInt(year);
  189. int month = Integer.parseInt(passwd.substring(size, size + 2));
  190. int day = Integer.parseInt(passwd.substring(size + 2, len));
  191. if (year >= 1950 && year < 2050 && month >= 1 && month <= 12 && day >= 1 && day <= 31) {
  192. level--;
  193. }
  194. }
  195. if (null != DICTIONARY && DICTIONARY.length > 0) {// dictionary
  196. for (int i = 0; i < DICTIONARY.length; i++) {
  197. if (passwd.equals(DICTIONARY[i]) || DICTIONARY[i].indexOf(passwd) >= 0) {
  198. level--;
  199. break;
  200. }
  201. }
  202. }
  203. if (len <= 6) {
  204. level--;
  205. if (len <= 4) {
  206. level--;
  207. if (len <= 3) {
  208. level = 0;
  209. }
  210. }
  211. }
  212. if (StringUtils.isCharEqual(passwd)) {
  213. level = 0;
  214. }
  215. if (level < 0) {
  216. level = 0;
  217. }
  218. return level;
  219. }
  220. /**
  221. *获得密码强度等级,包括简单、复杂、强、强、强
  222. *
  223. * @param passwd
  224. * @return
  225. */
  226. public static LEVEL getPasswordLevel(String passwd) {
  227. int level = checkPasswordStrength(passwd);
  228. switch (level) {
  229. case 0:
  230. case 1:
  231. case 2:
  232. case 3:
  233. return LEVEL.EASY;
  234. case 4:
  235. case 5:
  236. case 6:
  237. return LEVEL.MIDIUM;
  238. case 7:
  239. case 8:
  240. case 9:
  241. return LEVEL.STRONG;
  242. case 10:
  243. case 11:
  244. case 12:
  245. return LEVEL.VERY_STRONG;
  246. default:
  247. return LEVEL.EXTREMELY_STRONG;
  248. }
  249. }
  250. public static void main(String[] args) {
  251. String passwd = "-A12345abcs";
  252. System.out.println(CheckStrength.checkPasswordStrength(passwd));
  253. System.out.println(CheckStrength.getPasswordLevel(passwd));
  254. }
  255. }