強固なパスワードを生成する（再生成可能）

# 良いパスワードとは

- 思い出せる
- ユニーク
- ランダム

ランダムな文字列は覚えられない。
サービスごとにユニークにすると、思い出せなくなる。
覚えやすさと、強固なパスワードは両立は難しい。

# 仕組み
javascriptでhost名+シークレットキーの文字列からでhashを生成する。

- host名ごとにユニークになる
- 覚えておく必要があるのは、シークレットキーとhashアルゴリズムのみ
- javascriptが動く環境なら、どこでもスタンドアロンで使える
- ブックマークレットにしておけばワンクリックでパスワード入力できる


# 実装
host名+プロンプトで入力したシークレットキー
md5でhash
文字種増やすためにbase64でencode
input type="password"を探して値はめる

md5のコードはこちらを引用させて頂いています。
http://www.myersdaily.org/joseph/javascript/md5-text.html

```js
(function(){
  var str = prompt('input secret key');

// md5.js 引用start
function md5cycle(x, k) {
var a = x[0], b = x[1], c = x[2], d = x[3];

a = ff(a, b, c, d, k[0], 7, -680876936);
d = ff(d, a, b, c, k[1], 12, -389564586);
c = ff(c, d, a, b, k[2], 17,  606105819);
b = ff(b, c, d, a, k[3], 22, -1044525330);
a = ff(a, b, c, d, k[4], 7, -176418897);
d = ff(d, a, b, c, k[5], 12,  1200080426);
c = ff(c, d, a, b, k[6], 17, -1473231341);
b = ff(b, c, d, a, k[7], 22, -45705983);
a = ff(a, b, c, d, k[8], 7,  1770035416);
d = ff(d, a, b, c, k[9], 12, -1958414417);
c = ff(c, d, a, b, k[10], 17, -42063);
b = ff(b, c, d, a, k[11], 22, -1990404162);
a = ff(a, b, c, d, k[12], 7,  1804603682);
d = ff(d, a, b, c, k[13], 12, -40341101);
c = ff(c, d, a, b, k[14], 17, -1502002290);
b = ff(b, c, d, a, k[15], 22,  1236535329);

a = gg(a, b, c, d, k[1], 5, -165796510);
d = gg(d, a, b, c, k[6], 9, -1069501632);
c = gg(c, d, a, b, k[11], 14,  643717713);
b = gg(b, c, d, a, k[0], 20, -373897302);
a = gg(a, b, c, d, k[5], 5, -701558691);
d = gg(d, a, b, c, k[10], 9,  38016083);
c = gg(c, d, a, b, k[15], 14, -660478335);
b = gg(b, c, d, a, k[4], 20, -405537848);
a = gg(a, b, c, d, k[9], 5,  568446438);
d = gg(d, a, b, c, k[14], 9, -1019803690);
c = gg(c, d, a, b, k[3], 14, -187363961);
b = gg(b, c, d, a, k[8], 20,  1163531501);
a = gg(a, b, c, d, k[13], 5, -1444681467);
d = gg(d, a, b, c, k[2], 9, -51403784);
c = gg(c, d, a, b, k[7], 14,  1735328473);
b = gg(b, c, d, a, k[12], 20, -1926607734);

a = hh(a, b, c, d, k[5], 4, -378558);
d = hh(d, a, b, c, k[8], 11, -2022574463);
c = hh(c, d, a, b, k[11], 16,  1839030562);
b = hh(b, c, d, a, k[14], 23, -35309556);
a = hh(a, b, c, d, k[1], 4, -1530992060);
d = hh(d, a, b, c, k[4], 11,  1272893353);
c = hh(c, d, a, b, k[7], 16, -155497632);
b = hh(b, c, d, a, k[10], 23, -1094730640);
a = hh(a, b, c, d, k[13], 4,  681279174);
d = hh(d, a, b, c, k[0], 11, -358537222);
c = hh(c, d, a, b, k[3], 16, -722521979);
b = hh(b, c, d, a, k[6], 23,  76029189);
a = hh(a, b, c, d, k[9], 4, -640364487);
d = hh(d, a, b, c, k[12], 11, -421815835);
c = hh(c, d, a, b, k[15], 16,  530742520);
b = hh(b, c, d, a, k[2], 23, -995338651);

a = ii(a, b, c, d, k[0], 6, -198630844);
d = ii(d, a, b, c, k[7], 10,  1126891415);
c = ii(c, d, a, b, k[14], 15, -1416354905);
b = ii(b, c, d, a, k[5], 21, -57434055);
a = ii(a, b, c, d, k[12], 6,  1700485571);
d = ii(d, a, b, c, k[3], 10, -1894986606);
c = ii(c, d, a, b, k[10], 15, -1051523);
b = ii(b, c, d, a, k[1], 21, -2054922799);
a = ii(a, b, c, d, k[8], 6,  1873313359);
d = ii(d, a, b, c, k[15], 10, -30611744);
c = ii(c, d, a, b, k[6], 15, -1560198380);
b = ii(b, c, d, a, k[13], 21,  1309151649);
a = ii(a, b, c, d, k[4], 6, -145523070);
d = ii(d, a, b, c, k[11], 10, -1120210379);
c = ii(c, d, a, b, k[2], 15,  718787259);
b = ii(b, c, d, a, k[9], 21, -343485551);

x[0] = add32(a, x[0]);
x[1] = add32(b, x[1]);
x[2] = add32(c, x[2]);
x[3] = add32(d, x[3]);

}

function cmn(q, a, b, x, s, t) {
a = add32(add32(a, q), add32(x, t));
return add32((a << s) | (a >>> (32 - s)), b);
}

function ff(a, b, c, d, x, s, t) {
return cmn((b & c) | ((~b) & d), a, b, x, s, t);
}

function gg(a, b, c, d, x, s, t) {
return cmn((b & d) | (c & (~d)), a, b, x, s, t);
}

function hh(a, b, c, d, x, s, t) {
return cmn(b ^ c ^ d, a, b, x, s, t);
}

function ii(a, b, c, d, x, s, t) {
return cmn(c ^ (b | (~d)), a, b, x, s, t);
}

function md51(s) {
txt = '';
var n = s.length,
state = [1732584193, -271733879, -1732584194, 271733878], i;
for (i=64; i<=s.length; i+=64) {
md5cycle(state, md5blk(s.substring(i-64, i)));
}
s = s.substring(i-64);
var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
for (i=0; i<s.length; i++)
tail[i>>2] |= s.charCodeAt(i) << ((i%4) << 3);
tail[i>>2] |= 0x80 << ((i%4) << 3);
if (i > 55) {
md5cycle(state, tail);
for (i=0; i<16; i++) tail[i] = 0;
}
tail[14] = n*8;
md5cycle(state, tail);
return state;
}

/* there needs to be support for Unicode here,
 * unless we pretend that we can redefine the MD-5
 * algorithm for multi-byte characters (perhaps
 * by adding every four 16-bit characters and
 * shortening the sum to 32 bits). Otherwise
 * I suggest performing MD-5 as if every character
 * was two bytes--e.g., 0040 0025 = @%--but then
 * how will an ordinary MD-5 sum be matched?
 * There is no way to standardize text to something
 * like UTF-8 before transformation; speed cost is
 * utterly prohibitive. The JavaScript standard
 * itself needs to look at this: it should start
 * providing access to strings as preformed UTF-8
 * 8-bit unsigned value arrays.
 */
function md5blk(s) { /* I figured global was faster.   */
var md5blks = [], i; /* Andy King said do it this way. */
for (i=0; i<64; i+=4) {
md5blks[i>>2] = s.charCodeAt(i)
+ (s.charCodeAt(i+1) << 8)
+ (s.charCodeAt(i+2) << 16)
+ (s.charCodeAt(i+3) << 24);
}
return md5blks;
}

var hex_chr = '0123456789abcdef'.split('');

function rhex(n)
{
var s='', j=0;
for(; j<4; j++)
s += hex_chr[(n >> (j * 8 + 4)) & 0x0F]
+ hex_chr[(n >> (j * 8)) & 0x0F];
return s;
}

function hex(x) {
for (var i=0; i<x.length; i++)
x[i] = rhex(x[i]);
return x.join('');
}

function md5(s) {
return hex(md51(s));
}

/* this function is much faster,
so if possible we use it. Some IEs
are the only ones I know of that
need the idiotic second function,
generated by an if clause.  */

function add32(a, b) {
return (a + b) & 0xFFFFFFFF;
}

if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') {
function add32(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF),
msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
}
// md5.js 引用end

  // 16進から2進に
  function hex2binary(x) {
  for (var i=0, r=''; i<x.length; i++)
  r += ('000'+parseInt(x[i],16).toString(2)).slice(-4);
  return r;
  }

  // base64表現のmd5
  function md5base64(x) {
  x = hex2binary(md5(x));
  for (var i=0, r=''; i<x.length; i+=6)
  r += 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[parseInt((x.slice(i,i+6)+'11111').slice(0, 6),2)];
  while(r.length%4 != 0) r+='=';
  return r;
  }

  var generated = md5base64(location.host + str);
  var password = document.getElementsByTagName("input");
  var flag = false;
  // パスワード項目に設定
  for(var i = 0; i < password.length; i++){
    if(password[i].type != 'password') continue;
    flag = true;
    password[i].value = generated;
  }
  if(!flag)prompt('password' ,generated); // パスワード項目がなければalertする
})()
```

# ブックマークレットにする
uglifireで圧縮
シークレットキー"pasuwa-do"を書き換えてください。

```
javascript:!function(){function n(n,r){var a=n[0],c=n[1],f=n[2],i=n[3];a=t(a,c,f,i,r[0],7,-680876936),i=t(i,a,c,f,r[1],12,-389564586),f=t(f,i,a,c,r[2],17,606105819),c=t(c,f,i,a,r[3],22,-1044525330),a=t(a,c,f,i,r[4],7,-176418897),i=t(i,a,c,f,r[5],12,1200080426),f=t(f,i,a,c,r[6],17,-1473231341),c=t(c,f,i,a,r[7],22,-45705983),a=t(a,c,f,i,r[8],7,1770035416),i=t(i,a,c,f,r[9],12,-1958414417),f=t(f,i,a,c,r[10],17,-42063),c=t(c,f,i,a,r[11],22,-1990404162),a=t(a,c,f,i,r[12],7,1804603682),i=t(i,a,c,f,r[13],12,-40341101),f=t(f,i,a,c,r[14],17,-1502002290),c=t(c,f,i,a,r[15],22,1236535329),a=o(a,c,f,i,r[1],5,-165796510),i=o(i,a,c,f,r[6],9,-1069501632),f=o(f,i,a,c,r[11],14,643717713),c=o(c,f,i,a,r[0],20,-373897302),a=o(a,c,f,i,r[5],5,-701558691),i=o(i,a,c,f,r[10],9,38016083),f=o(f,i,a,c,r[15],14,-660478335),c=o(c,f,i,a,r[4],20,-405537848),a=o(a,c,f,i,r[9],5,568446438),i=o(i,a,c,f,r[14],9,-1019803690),f=o(f,i,a,c,r[3],14,-187363961),c=o(c,f,i,a,r[8],20,1163531501),a=o(a,c,f,i,r[13],5,-1444681467),i=o(i,a,c,f,r[2],9,-51403784),f=o(f,i,a,c,r[7],14,1735328473),c=o(c,f,i,a,r[12],20,-1926607734),a=e(a,c,f,i,r[5],4,-378558),i=e(i,a,c,f,r[8],11,-2022574463),f=e(f,i,a,c,r[11],16,1839030562),c=e(c,f,i,a,r[14],23,-35309556),a=e(a,c,f,i,r[1],4,-1530992060),i=e(i,a,c,f,r[4],11,1272893353),f=e(f,i,a,c,r[7],16,-155497632),c=e(c,f,i,a,r[10],23,-1094730640),a=e(a,c,f,i,r[13],4,681279174),i=e(i,a,c,f,r[0],11,-358537222),f=e(f,i,a,c,r[3],16,-722521979),c=e(c,f,i,a,r[6],23,76029189),a=e(a,c,f,i,r[9],4,-640364487),i=e(i,a,c,f,r[12],11,-421815835),f=e(f,i,a,c,r[15],16,530742520),c=e(c,f,i,a,r[2],23,-995338651),a=u(a,c,f,i,r[0],6,-198630844),i=u(i,a,c,f,r[7],10,1126891415),f=u(f,i,a,c,r[14],15,-1416354905),c=u(c,f,i,a,r[5],21,-57434055),a=u(a,c,f,i,r[12],6,1700485571),i=u(i,a,c,f,r[3],10,-1894986606),f=u(f,i,a,c,r[10],15,-1051523),c=u(c,f,i,a,r[1],21,-2054922799),a=u(a,c,f,i,r[8],6,1873313359),i=u(i,a,c,f,r[15],10,-30611744),f=u(f,i,a,c,r[6],15,-1560198380),c=u(c,f,i,a,r[13],21,1309151649),a=u(a,c,f,i,r[4],6,-145523070),i=u(i,a,c,f,r[11],10,-1120210379),f=u(f,i,a,c,r[2],15,718787259),c=u(c,f,i,a,r[9],21,-343485551),n[0]=s(a,n[0]),n[1]=s(c,n[1]),n[2]=s(f,n[2]),n[3]=s(i,n[3])}function r(n,r,t,o,e,u){return r=s(s(r,n),s(o,u)),s(r<<e|r>>>32-e,t)}function t(n,t,o,e,u,a,c){return r(t&o|~t&e,n,t,u,a,c)}function o(n,t,o,e,u,a,c){return r(t&e|o&~e,n,t,u,a,c)}function e(n,t,o,e,u,a,c){return r(t^o^e,n,t,u,a,c)}function u(n,t,o,e,u,a,c){return r(o^(t|~e),n,t,u,a,c)}function a(r){txt="";var t,o=r.length,e=[1732584193,-271733879,-1732584194,271733878];for(t=64;t<=r.length;t+=64)n(e,c(r.substring(t-64,t)));r=r.substring(t-64);var u=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(t=0;t<r.length;t++)u[t>>2]|=r.charCodeAt(t)<<(t%4<<3);if(u[t>>2]|=128<<(t%4<<3),t>55)for(n(e,u),t=0;16>t;t++)u[t]=0;return u[14]=8*o,n(e,u),e}function c(n){var r,t=[];for(r=0;64>r;r+=4)t[r>>2]=n.charCodeAt(r)+(n.charCodeAt(r+1)<<8)+(n.charCodeAt(r+2)<<16)+(n.charCodeAt(r+3)<<24);return t}function f(n){for(var r="",t=0;4>t;t++)r+=v[n>>8*t+4&15]+v[n>>8*t&15];return r}function i(n){for(var r=0;r<n.length;r++)n[r]=f(n[r]);return n.join("")}function l(n){return i(a(n))}function s(n,r){return n+r&4294967295}function s(n,r){var t=(65535&n)+(65535&r),o=(n>>16)+(r>>16)+(t>>16);return o<<16|65535&t}function h(n){for(var r=0,t="";r<n.length;r++)t+=("000"+parseInt(n[r],16).toString(2)).slice(-4);return t}function g(n){n=h(l(n));for(var r=0,t="";r<n.length;r+=6)t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[parseInt((n.slice(r,r+6)+"11111").slice(0,6),2)];for(;t.length%4!=0;)t+="=";return t}var d=location.host+prompt('input secret key'),v="0123456789abcdef".split("");"5d41402abc4b2a76b9719d911017c592"!=l("hello");for(var p=g(d),b=document.getElementsByTagName("input"),A=!1,C=0;C<b.length;C++)"password"==b[C].type&&(A=!0,b[C].value=p);A||prompt("password",p)}();
```

# gist
```
javascript:(function(d){s=d.createElement('script');s.src='https://cdn.rawgit.com/onfi/998d7e3696926039fa99/raw/00b95a9a852358a995483fc624eaa0cffccf9e6a/password.js';d.body.appendChild(s);})(document)
```