// passchk.js is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// passchk.js is distributed in the hope that it will be useful but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// The passchk.js archive has a copy of the GNU General Public License,
// but if you did not get it, see <http://www.gnu.org/licenses/>
//
// passchk.js is available from http://rumkin.com/tools/password/passchk.php
//
// Javascript functions for the password checker form
var Frequency_List = "gL6-A$A:#@'$KT#<c\"06\"8*\"Wb\"5-$Kr t%#f+\"S4$7;$ v!R=%!6 g@#s}&'P#rM\"a8\"K'!3= #V }o wx*bZ\"X=\"De#2 #~B!dL!\\\\\"(u qj#Pf L_\"e (1K$9--x6 SE\"x- .$)/s%rK(w\"\"QV\"oQ ;; {_ [| q@(8t-G7#nU MW cS2$9 UJ GH <]*#S !: >!'kQ \\Z @A)O8 5& E (L\"\"YZ r_&g2 66 ~& *L!n* zO,|Y)B8 V.#X: qI'V0 B7 s@4<B)>= I-$wt!;A =h ?G+y: p/ |k\"}} &w\"]?#72 W) j$ @w S !I700V'gf (Q cf!9{9cL Qa .i #Z, F *M NZ!0c RX!+%((N S$ ]o#hU#{o Z2#j_ 6P d% I!!wX _Z.nH!i.!@y!6T#a$\"Yt ?]!kv Jl\"]{ sh!2$&x~\"5F.8X AF!n2 :A1G@('.%5} 24!TZ XY \\P zq G,).J)>} GD _o Xu*di&m0!%Q  L-KA @I ei%4P <S 8m+NI l& Gg&m+\"nS$T{%&? YT e( Mu g2 ~., B(\\P N6 .d .M:^6 gg\"]s\"k2':6 LU /h#k_ 6-#$3%p9 W$ 7x&)(%_-\">[#Q8 VM y( 3q c* vn/va-K> ^N Il LQ/y9 qF *< /k+^O zp K;\"bZ!M\\!>(*NW L' .-#=<\"Uz$^:$o? C] F' /)\"+) FC+8H$M&!l1&2'#n\"&K<!d-#\"_ jw A{ J(#~e$Yi#(v.Ng#NF!V8 zM\"Q4*RH&.X E\"\"n; ^5 41 gM!xj(\"Q1![ bn #!\";?1la yU mR A6)GK @=\"w5!k$!bX\"b[)K-!R) Mq Fl&uz Zx&p\\ <A X' f&!B_ xj)GW.3F <G *5 .e-}6 (6 C-!U>)S< :r#=;#:C 9Q!xJ,7< w\" Tp#*1%|F#Ze&JW Dn /$ ](\"4( H{&>!.@h W[ .F\"G}/#k :_ ,U ;$04E \\,!/P)h9!Hq f4( f S& 18 M^\":'#w|#]o 7= !# Y]\"*4 YZ-<E0$]\"B^ QO bn/$G )> zO e>-|+ \\? SY (d$nj b%)p+%aQ 2P oa!U\\ mp$x: S: *$ &.!9( 3-3KD&WW WG\"jB'`),:t I<'T_ I=($C Pd!;M 5I 3a\"h %_G $, .E (_%wZ(WC!*] w> \"$ s} WT h;*Kd UY!JW\")u\",)\"v6!AU\"Mv RS\"hZ \"(\"Ya&e/%5S-w\\\"/W#b1 lF*fp%a6$3c$aH#uf!e> cH!]v 58*En+r< Ic v< gh,&\\ +A ;a$2!)I. !8 :w$>E 2Q fH+LA$)$ Gl+NL\"y9\"43$30 \"8 d% 8l u% cV$pm 6C 2O uH .S K@ $= DB B(!f6 =9 <R *I uH A@ dG )A `K NX 3L !sopL %: o1 h0 9/ (U(5?-Q8!&=!iX\"f(0\\[ ~V!ii )\\,<? 2W!l*!}#\"\\8#NX)pn S0 Iv!{M$Rs#A2#s\"!$R k& ]J!Yi {#4jR%m` --$\\D ;(*>X ]K lS\"H~'c; ;K#hP!/^!(l !S#z+##d [H F\\%Z3/b-#)f /O c% 66!YO 2w+{3,}? {N I1  O3^6 !? xV\"s5-3I `R wn (E wj Kq';: KA XU&_'#b|$<N$2C qX w# iu!yO Fr($1\"T@\"pg\"eA#+3'g<!w$\":w `7$\\ !Z)#qf%I4%$x*pf!kN\"/* T9(Z])+?&O5\"9\"!nP 2< {9 5q R-'0~5)4 ^= j8 us9#/ @1 }3 Ul0+- U6 *K!&? +K!]p()0 Z$ va!e} Y< fl!rQ *) C( KJ#f4 $;'v.5aO W` w*!A<0IC yG ru!KR-*/ <\\ ,-!&3!Ap&Jc'+` V& s5\"gB$gF!`>!B0 hO g. ;w\"I5 |v7:@&:o %h#zz H\"(wx tL rk!q\\*w9 {D Q-!T_!lF!O$%vF&cB 8 \"Mp!SZ'he!HP rq!>N\"BA\"Y3 wR8^U$.~ ee#K[\";,#IZ ;f!KI!eE!XQ d-#s/$JY%Pz%/F$+Y#2$ XX#Ez'5g$z9\"9$!1y vB 51!La @T*\\f0)j ek L3!^@1t- II Zn m@,08 )0!-@!<-! |\"Fp&Oj A& N_ U[ P>!-h$D` 3a!K' `d#uc%";
var Common_Words = ["123456", "123456789", "password", "12345678", "qwerty", "passwort", "passwort1", "qwert", "asdf", "qwertz", "1234567", "111111", "123123", "1234567890", "000000", "abc123", "1234", "macromedia", "azerty", "iloveyou", "aaaaaa", "654321", "12345", "666666", "sunshine", "123321", "letmein", "monkey", "asdfgh", "password1", "shadow", "princess", "dragon", "daniel", "computer", "michael", "121212", "charlie", "master", "superman", "qwertzuiop", "112233", "asdfasdf", "jessica", "1q2w3e4r", "welcome", "1qaz2wsx", "987654321", "fdsa", "753951", "chocolate", "fuckyou", "soccer", "tigger", "asdasd", "thomas", "asdfghjkl", "internet", "michelle", "football", "123qwe", "zxcvbnm", "7777777", "qazwsx", "baseball", "jennifer", "jordan", "abcd1234", "trustno1", "buster", "555555", "liverpool", "abc", "whatever", "11111111", "102030", "123123123", "andrea", "pepper", "nicole", "killer", "abcdef", "hannah", "test", "alexander", "andrew", "222222", "joshua", "freedom", "samsung", "asdfghj", "purple", "ginger", "123654", "matrix", "secret", "summer", "1q2w3e", "snoopy1", "sommer", "herbst", "winter", "fr\u00fchling"];
document.Frequency_Parsed = 0;

var Frequency_Table = new Array();

// The frequency thing is a bit more interesting, but still not too complex.
// Each three letters are base-95 encoded number representing the chance that
// this combination comes next.  Subtract the value of ' ' from each of the
// three, then ((((first_value * 95) + second_value) * 95) + third_value) will
// give you the odds that this pair is grouped together.  The first is "  "
// (non-alpha chars), then " a", " b", etc. " y", " z", "a ", "aa", "ab", and
// so on.  If you decrypt the table successfully, you should see a really large
// number for "qu".
function Parse_Frequency_Token() {
	var c;

	c = Frequency_List.charCodeAt(0) - ' '.charCodeAt(0);
	c /= 95;
	c += Frequency_List.charCodeAt(1) - ' '.charCodeAt(0);
	c /= 95;
	c += Frequency_List.charCodeAt(2) - ' '.charCodeAt(0);
	c /= 95;

	Frequency_List = Frequency_List.substr(3, Frequency_List.length);

	Frequency_Table[Frequency_Table.length] = c;
}

function Parse_Frequency() {
	for (var i = 0; i < 100 && Frequency_List.length > 0; i++) {
		Parse_Frequency_Token();
	}
	if (Frequency_List.length) {
		window.setTimeout('Parse_Frequency()', 20);
	} else {
		document.Frequency_Parsed = 1;
	}
}

function Get_Index(c) {
	c = c.charAt(0).toLowerCase();
	if (c < 'a' || c > 'z') {
		return 0;
	}
	return c.charCodeAt(0) - 'a'.charCodeAt(0) + 1;
}

function Get_Charset_Size(pass) {
	var a = 0, u = 0, n = 0, ns = 0, r = 0, sp = 0, s = 0, chars = 0;

	for (var i = 0; i < pass.length; i++) {
		var c = pass.charAt(i);

		if (a == 0 && 'abcdefghijklmnopqrstuvwxyz'.indexOf(c) >= 0) {
			chars += 26;
			a = 1;
		}
		if (u == 0 && 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.indexOf(c) >= 0) {
			chars += 26;
			u = 1;
		}
		if (n == 0 && '0123456789'.indexOf(c) >= 0) {
			chars += 10;
			n = 1;
		}
		if (ns == 0 && '!@#$%^&*()'.indexOf(c) >= 0) {
			chars += 10;
			ns = 1;
		}
		if (r == 0 && "`~-_=+[{]}\\|;:'\",<.>/?".indexOf(c) >= 0) {
			chars += 20;
			r = 1;
		}
		if (sp == 0 && c == ' ') {
			chars += 1;
			sp = 1;
		}
		if (s == 0 && (c < ' ' || c > '~')) {
			chars += 32 + 128;
			s = 1;
		}
	}

	return chars;
}

function getPasswordStrength(pass) {
	if (document.Frequency_Parsed == 0) {
		return 0;
	}

	var plower = pass.toLowerCase();
	var r = "";
	var bits = 0;
	// Penalty fo short passwords
	if (pass.length <= 4) {
		return 0;
	} else if (pass.length < 8) {
		//bits = -10;
	}

	// First, see if it is a common password.
	for (var i = 0; i < Common_Words.length; i++) {
		if (Common_Words[i] == plower) {
			return 0;
		}
	}

	// Calculate frequency chance
	if (pass.length > 1) {
		var c, aidx = 0, charSet;
		charSet = Math.log(Get_Charset_Size(pass)) / Math.log(2);
		aidx = Get_Index(plower.charAt(0));
		for (var b = 1; b < plower.length; b++) {
			var bidx = Get_Index(plower.charAt(b));
			c = 1.0 - Frequency_Table[aidx * 27 + bidx];
			bits += charSet * c * c;
			// Squared = assmume they are good guessers
			aidx = bidx;
		}
		return Math.max(0, bits);
	}
}

window.setTimeout('Parse_Frequency()', 100);
