1var letters = "abcdefghijklmnopqrstuvwxyz"; 2var numbers = "01234567890"; 3var symbols = ")!@#$%^&*()"; 4var uLetters = letters.toUpperCase(); 5 6function getType(char){ 7 if(letters.indexOf(char) > -1){ 8 return "letter"; 9 } 10 if(uLetters.indexOf(char) > -1){ 11 return "uLetter"; 12 } 13 if(numbers.indexOf(char) > -1){ 14 return "number"; 15 } 16 //if(symbols.indexOf(char) > -1){ 17 return "symbol"; 18 //} 19} 20 21function reverseStr(str){ 22 var result = ""; 23 for(var i = str.length - 1; i > -1; i--){ 24 result += str[i]; 25 } 26 return result; 27} 28 29function calculateRepeatIncrement(password, index){ 30 var len = password.length; 31 var increment = 0; 32 for(var t = 0; t < len; t++){ 33 if(index !== t && password[index] === password[t]){ 34 increment += len/Math.abs(index - t); 35 } 36 } 37 return increment; 38} 39 40function calculateSequence(password, str){ 41 var result = 0; 42 var lPass = password.toLowerCase(); 43 var len = str.length - 3; 44 45 for (var i=0; i < len; i++) { 46 var forward = str.substring(i, i + 3); 47 var reverse = reverseStr(forward); 48 if (lPass.indexOf(forward) > -1 || lPass.indexOf(reverse) > -1) { 49 result++; 50 } 51 } 52 return result; 53} 54 55function strongPass(password, config){ 56 var score = 0; 57 var len = password.length; 58 var minLength = config && config.minLength || 8; 59 60 var numULetter = 0, 61 numLLetter = 0, 62 numNumber = 0, 63 numSymbol = 0, 64 numMiddle = 0, 65 lastULetter = -1, 66 lastLLetter = -1, 67 lastNumber = -1, 68 lastSymbol = -1, 69 numConsecLLetter = 0, 70 numConsecULetter = 0, 71 numConsecNumber = 0, 72 numConsecSymbol = 0, 73 numRepeat = 0, 74 numRepeatChars = 0; 75 76 77 for(var i = 0; i < len; i++){ 78 var type = getType(password[i]); 79 80 if(type === 'letter'){ 81 if(lastLLetter > -1 && lastLLetter + 1 === i){ 82 numConsecLLetter++; 83 } 84 lastLLetter = i; 85 numLLetter++; 86 } 87 if(type === 'uLetter'){ 88 if(lastULetter > -1 && lastULetter + 1 === i){ 89 numConsecULetter++; 90 } 91 lastULetter = i; 92 numULetter++; 93 } 94 if(type === 'number'){ 95 if(lastNumber > -1 && lastNumber + 1 === i){ 96 numConsecNumber++; 97 } 98 lastNumber = i; 99 numNumber++; 100 } 101 if(type === 'symbol'){ 102 if(lastSymbol > -1 && lastSymbol + 1 === i){ 103 numConsecSymbol++; 104 } 105 lastSymbol = i; 106 numSymbol++; 107 } 108 if(i > 0 && i < len - 1 && ['number', 'symbol'].indexOf(type) > -1){ 109 numMiddle++; 110 } 111 112 var increment = calculateRepeatIncrement(password, i); 113 if(increment){ 114 numRepeat += increment; 115 numRepeatChars++; 116 numRepeat = (len - numRepeatChars) ? Math.ceil(numRepeat/(len - numRepeatChars)) : Math.ceil(numRepeat); 117 } 118 } 119 120 score += password.length * 4; 121 122 if(numULetter > 0 && numULetter < len){ 123 score += (len - numULetter) * 2; 124 } 125 if(numLLetter > 0 && numLLetter < len){ 126 score += (len - numLLetter) * 2; 127 } 128 if(numNumber > 0 && numNumber < len){ 129 score += numNumber * 4; 130 } 131 132 score += numSymbol * 6; 133 score += numMiddle * 2; 134 135 if(numULetter + numLLetter > 0 && numNumber + numSymbol === 0){ 136 score -= len; 137 } 138 139 if(numNumber === len){ 140 score -= len; 141 } 142 143 score -= numRepeat; 144 145 score -= numConsecULetter * 2; 146 score -= numConsecLLetter * 2; 147 score -= numConsecNumber * 2; 148 149 score -= calculateSequence(password, letters) * 3; 150 score -= calculateSequence(password, numbers) * 3; 151 score -= calculateSequence(password, symbols) * 3; 152 153 if(len > minLength){ 154 var requirements = numLLetter ? 1 : 0; 155 requirements += numULetter ? 1 : 0; 156 requirements += numNumber ? 1 : 0; 157 requirements += numSymbol ? 1 : 0; 158 159 if(requirements > 2){
160 score += requirements * 2 + 2; 161 } 162 } 163 164 if(score < 0){ 165 score = 0; 166 } else if(score > 100){ 167 score = 100; 168 } 169 170 171 return score; 172} 173 174function toNumber(password, options){ 175 var number = strongPass(password, options); 176 if(number === 100){ 177 number = 99; 178 } 179 return Math.floor((number + 20)/20); 180} 181 182function toMark(password, options){ 183 var number = toNumber(password, options); 184 if(number === 1){ 185 return 'Very Weak'; 186 } 187 if(number === 2){ 188 return 'Weak'; 189 } 190 if(number === 3){ 191 return 'Good'; 192 } 193 if(number === 4){ 194 return 'Strong'; 195 } 196 if(number === 5){ 197 return 'Very Strong'; 198 } 199} 200 201toNumber.engine = strongPass; 202toNumber.toMark = toMark;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.