Hatena::ブログ(Diary)

(TooLab.)Lab. 研究日誌 このページをアンテナに追加 RSSフィード Twitter

2018 January 13

KeePass の添付ファイル用クレジットカード雛形

前記事に翌日書くって宣言しておきながらこのザマですよ。

それはともかく、今回も KeePass の添付ファイルネタです。
タイトル通りクレジットカードの雛形です。

確認した環境は Windows 7 x64 + IE11 + KeePass 2.38 です。
ちなみに KeePass データビューワは IE コンポーネントが使用されており、私の環境ではドキュメントモードは 11、ユーザエージェントは Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Win64; x64; Trident/7.0;(省略)) と互換モード、location.href は about:blank となります。
※試したところ IE コンポを IE 9 以降に対応させる例のレジストリをゴニョゴニョすれば互換モードは解除できます。

f:id:barrackdo:20180112005915p:image:w400
このような感じになります。
各情報部分をマウスクリックすると選択状態になるのでクリップボードにコピーしやすくなります。
セキュリティコードの箇所はマウスホバーでマスクが解除されます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Credit Card</title>
<style>
main {display: block; position: relative; width: 425px; height: 270px; background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MjUiIGhlaWdodD0iMjcwIiB2aWV3Qm94PSIwIDAgMSAxIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj4NCjxsaW5lYXJHcmFkaWVudCBpZD0iZzExOSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjAlIj4NCjxzdG9wIHN0b3AtY29sb3I9IiNBOEE4QTgiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiM2NDY0NjQiIG9mZnNldD0iMSIvPg0KPC9saW5lYXJHcmFkaWVudD4NCjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSI0MjUiIGhlaWdodD0iMjcwIiBmaWxsPSJ1cmwoI2cxMTkpIi8+DQo8L3N2Zz4='); margin: auto;}

.cc {position: absolute; height: 20px; background-color: rgba(255,255,255,0.75); border: none; font-family: Consolas, 'Courier New', Courier, Monaco, monospace; font-size: 22px; text-align: center;}
#card_number {top: 147px; left: 30px; width: 372px;}
#month {top: 192px; left: 192px; width: 40px;}
#year {top: 192px; left: 246px; width: 40px;}
#security_code {top: 192px; left: 347px; width: 55px;}
#name {top: 227px; left: 192px; width: 210px;}
#svg {position: absolute; top: 192px; left: 44px;}

#slash {position: absolute; top: 192px; left: 234px; background-color: rgba(255,255,255,0.75); stroke: #000000;}
.corners {position: absolute;}
#corner_tl {top: 0; left: 0;}
#corner_tr {top: 0; right: 0;}
#corner_bl {bottom: 0; left: 0;}
#corner_br {bottom: 0; right: 0;}
</style>
<script>
document.addEventListener('DOMContentLoaded',function(){
	var data = {
		card_number:   '0123456789012345',
		month:         '12',
		year:          '2034',
		security_code: '567',
		name:          'TARO YAMADA',
		brand:         'V'
	},
	imgsrc = "";
	
	
	
	var d = document,
	qs = 'querySelector',
	cn = d[qs]('#card_number'),
	mm = d[qs]('#month'),
	yy = d[qs]('#year'),
	sc = d[qs]('#security_code'),
	nn = d[qs]('#name'),
	separates = function(n){var a,x=0,s=[];switch(n.length){case 16:a=[4,4,4,4];break;case 15:a=[4,6,5];break;case 14:a=[4,6,4];break;}for(var i=0,l=a.length;l>i;i++){s.push(n.substr(x,a[i]));x+=a[i];}return s.join(' ');};
	d.createElementSVG=function(e){e=d.createElementNS('http://www.w3.org/2000/svg',e);e.prop=function(o){for(var k in o){e.setAttribute(k,o[k]);}};e.appendTo=function(p){p.appendChild(e);};return e;};
	var brands = {
		V: [
			{e:'svg',a:{id:'svg',width:96,height:48,viewBox:'0 0 1280 640'},p:'main'},
			{e:'rect',a:{x:0,y:0,width:1280,height:640,rx:40,ry:40,fill:'rgba(255,255,255,1)'},p:'#svg'},
			{e:'path',a:{d:'M76,142 l-2,12 l78,20 q30,10,44,82 l64,242 l96,0 l148,-356 l-98,0 l-94,242 l-38,-200 q-4,-42,-68,-42 l-130,0Z',fill:'rgba(26,31,113,1)'},p:'#svg'},
			{e:'path',a:{d:'M544,142 l-76,356 l90,0 l76,-356 l-90,0Z',fill:'rgba(26,31,113,1)'},p:'#svg'},
			{e:'path',a:{d:'M900,152 q-202,-54,-240,88 q-8,60,60,100 q78,32,66,64 q-34,52,-148,2 l-16,78 q200,60,256,-68 q20,-80,-54,-120 q-90,-40,-64,-68 q40,-40,124,2 l16,-78Z',fill:'rgba(26,31,113,1)'},p:'#svg'},
			{e:'path',a:{d:'M1132,142 l-60,0 q-48,0,-62,40 l-132,316 l96,0 l20,-54 l116,0 l-14,-72 l-76,0 l48,-132 l54,258 l86,0 l-76,-356Z',fill:'rgba(26,31,113,1)'},p:'#svg'}
		],
		M: [
			{e:'svg',a:{id:'svg',width:96,height:48,viewBox:'0 0 1280 640'},p:'main'},
			{e:'rect',a:{x:0,y:0,width:1280,height:640,rx:40,ry:40,fill:'rgba(255,255,255,1)'},p:'#svg'},
			{e:'path',a:{d:'M640,120 a255,255 0 1,0 0,400 a255,255 0 0,1 0,-400Z',fill:'rgba(235,0,27,1)'},p:'#svg'},
			{e:'path',a:{d:'M640,120 a255,255 0 1,1 0,400 a255,255 0 0,0 0,-400Z',fill:'rgba(247,158,27,1)'},p:'#svg'},
			{e:'path',a:{d:'M640,120 a255,255 0 0,0 0,400 a255,255 0 0,0 0,-400',fill:'rgba(255,95,0,1)'},p:'#svg'}
		],
		A: [
			{e:'svg',a:{id:'svg',width:96,height:48,viewBox:'0 0 1280 640'},p:'main'},
			{e:'rect',a:{x:0,y:0,width:1280,height:640,rx:40,ry:40,fill:'rgba(255,255,255,1)'},p:'#svg'},
			{e:'rect',a:{x:0,y:77,width:1280,height:486,fill:'rgba(255,255,255,1)'},p:'#svg'},
			{e:'path',a:{d:'M0,77 l0,232 l79,-182 l173,0 l21,43 l0,-43 l203,0 l43,99 l43,-99 l496,0 l51,59 l51,-59 l120,0 l0,-50 l-1280,0Z',fill:'rgba(0,38,99,1)'},p:'#svg'},
			{e:'path',a:{d:'M0,457 l120,-276 l96,0 l113,260 l0,-260 l107,0 l87,190 l80,-190 l109,0 l0,276 l-67,0 l0,-216 l-96,216 l-59,0 l-96,-216 l0,216 l-134,0 l-94,-229 l-46,112 l92,0 l23,56 l-138,0 l-25,61 l-72,0Z',fill:'rgba(0,38,99,1)'},p:'#svg'},
			{e:'path',a:{d:'M1026,181 l-264,0 l0,276 l264,0 l82,-90 l82,90 l89,0 l-126,-138 l70,0 l57,62 l0,-124 l-57,62 l-70,0 l126,-138 l-89,0 l-82,90 l-82,-90 l-34,59 l72,79 l-72,79 -164,0 l0,-51 l146,0 l0,-56 l-146,0 l0,-51 l164,0 34,-59Z',fill:'rgba(0,38,99,1)'},p:'#svg'},
			{e:'path',a:{d:'M0,513 l112,0 l26,-62 l57,0 l26,62 l221,0 l0,-46 l20,46 l115,0 l20,-46 l0,46 l455,0 l56,-60 l56,60 l116,0 l0,50 l-1280,0 l0,-50Z',fill:'rgba(0,38,99,1)'},p:'#svg'}
		],
		J: [
			{e:'svg',a:{id:'svg',width:96,height:48,viewBox:'0 0 1280 640'},p:'main'},
			{e:'rect',a:{x:0,y:0,width:1280,height:640,rx:40,ry:40,fill:'rgba(255,255,255,1)'},p:'#svg'},
			{e:'path',a:{d:'M1047,6 l-695,0 a120,120 0 0,0 -120,120 l0,508 l695,0 a120,120 0 0,0 120,-120 l0,-508Z',stroke:'rgba(0,0,0,0.1)',fill:'rgba(255,255,255,1)'},p:'#svg'},
			{e:'path',a:{d:'M501,48 l-135,0 a88,88 0 0,0 -88,88 l0,226 q114,50,127,-20 l0,-110 l77,0 l0,110 q-9,98,-204,58 l0,191 l135,0 a88,88 0 0,0 88,-88 l0,-455Z',fill:'rgba(0,111,188,1)'},p:'#svg'},
			{e:'path',a:{d:'M752,48 l-135,0 a88,88 0 0,0 -88,88 l0,121 q57,-48,198,-18 l0,39 q-136,-58,-148,42 q12,100,148,42 l0,39 q-141,30,-198,-18 l0,208 l135,0 a88,88 0 0,0 88,-88 l0,-455Z',fill:'rgba(230,0,57,1)'},p:'#svg'},
			{e:'path',a:{d:'M1003,48 l-135,0 a88,88 0 0,0 -88,88 l0,97 l135,0 a52,42 0 0,1 0,85 a62,44 0 0,1 0,89 l-91,0 l0,-148 l52,0 a18,22 0 0,1 0,44 l-52,0 l0,27 l56,0 a21,24 0 0,1 0,48 l-56,0 l0,29 l-44,0 l0,184 l135,0 a88,88 0 0,0 88,-88 l0,-455Z',fill:'rgba(92,181,49,1)'},p:'#svg'}
		],
		D: [
			{e:'svg',a:{id:'svg',width:96,height:48,viewBox:'0 0 1280 640'},p:'main'},
			{e:'rect',a:{x:0,y:0,width:1280,height:640,rx:40,ry:40,fill:'rgba(255,255,255,1)'},p:'#svg'},
			{e:'path',a:{d:'M573,68 a252,252 0 1,0 0,504 l133,0 a252,252 0 1,0 0,-504 l-133,0Z',fill:'rgba(0,121,190,1)'},p:'#svg'},
			{e:'path',a:{d:'M524,94 a225,225 0 1,0 105,450 l0,-362 a146,146 0 0,1 0,274 l0,88 a225,225 0 1,0 -105,-450 l0,362 a146,146 0 0,1 0,-274 l0,-88Z',fill:'rgba(255,255,255,1)'},p:'#svg'}
		]
	},
	brand = '';
	
	if(imgsrc.match(/^data:image\/(?:png|jpeg|gif|svg\+xml|webp);base64,[A-Za-z0-9\+\/=]+$/)){d[qs]('main').style.backgroundImage='url("'+imgsrc+'")';}
	
	brand = brands[data['brand'].toUpperCase()];
	for(var i = 0, l = brand.length; l > i; i++){
		var o = brand[i];
		var e = d.createElementSVG(o['e']);
		e.prop(o['a']);
		e.appendTo(d[qs](o['p']));
	}
	
	cn.dataset.sequence = data['card_number'];
	cn.dataset.separate = separates(data['card_number']);
	cn.value = cn.dataset.separate;
	cn.addEventListener('focus',function(){this.value = this.dataset.sequence;this.select();},false);
	cn.addEventListener('blur',function(){this.value = this.dataset.separate;},false);
	
	mm.dataset.val = data['month']
	mm.value = mm.dataset.val;
	mm.addEventListener('focus',function(){this.select();},false);
	
	yy.dataset.full = data['year'];
	yy.dataset.val = data['year'].slice(-2);
	yy.title = yy.dataset.full;
	yy.value = yy.dataset.val;
	yy.addEventListener('focus',function(){this.select();},false);
	
	sc.dataset.val = data['security_code'];
	sc.value = sc.dataset.val;
	sc.addEventListener('focus',function(){this.select();},false);
	sc.addEventListener('mouseenter',function(){this.type = 'text';},false);
	sc.addEventListener('mouseleave',function(){this.type = 'password';},false);
	
	nn.dataset.val = data['name'];
	nn.value = nn.dataset.val;
	nn.addEventListener('focus',function(){this.select();},false);
	
},false);
</script>
</head>
<body>
<main>
<input type="text" id="card_number" class="cc" readonly>
<input type="text" id="month" class="cc" readonly>
<input type="text" id="year" class="cc" readonly>
<input type="password" id="security_code" class="cc" readonly>
<input type="text" id="name" class="cc" readonly>
<svg id="slash" width="12" height="22" viewBox="0 0 12 20"><path d="M11,1,L1,19Z"></path></svg>
<svg id="corner_tl" class="corners" width="16" height="16" viewBox="0 0 16 16"><path d="M16,0,A16,16,0,0,0,0,16,L0,0Z" fill="#ffffff"></path></svg>
<svg id="corner_tr" class="corners" width="16" height="16" viewBox="0 0 16 16"><path d="M0,0,A16,16,0,0,1,16,16,L16,0Z" fill="#ffffff"></path></svg>
<svg id="corner_bl" class="corners" width="16" height="16" viewBox="0 0 16 16"><path d="M0,0,A16,16,0,0,0,16,16,L0,16Z" fill="#ffffff"></path></svg>
<svg id="corner_br" class="corners" width="16" height="16" viewBox="0 0 16 16"><path d="M16,0,A16,16,0,0,1,0,16,L16,16Z" fill="#ffffff"></path></svg>
</main>
</body>
</html>

上のコードをコピーして、テキストに貼り付けて保存し拡張子を .html としてください。
内容を書き換えて、日本語(ひらがな、カタカナ、漢字)などのマルチバイト文字を使った場合は文字コードを UTF-8 にするのを忘れずに。
ちなみにカードのサイズは 425×270px になっていますが、Vプリカを参考にしたためです。

	var data = {
		card_number:   '0123456789012345',
		month:         '12',
		year:          '2034',
		security_code: '567',
		name:          'TARO YAMADA',
		brand:         'V'
	},

ここの部分を適宜自分のカードの情報に書き換えてください。
一番下の brand は国際ブランドの頭文字で以下の5つに対応しています。
wikipedia:クレジットカードの国際ブランドに選出されているうちから、現時点で国内の会社から発行されていない DISCOVER と国内ではほぼ発行されてないだろう銀聯(China UnionPay)を除いたものです。


VVisa
MMasterCard
AAmerican Express
JJCB
DDiners Club

f:id:barrackdo:20180112010136p:image f:id:barrackdo:20180112010133p:image

f:id:barrackdo:20180112010125p:image f:id:barrackdo:20180112010131p:image

f:id:barrackdo:20180112010128p:image
各ロゴは SVG で描画してるんですが、American Express だけ普通にロゴ書くと大変なので大幅に略してあります。ごめんなさい。

また、以下の部分を編集することで背景画像を変更できます。

	imgsrc = "";

ただし、おそらくセキュリティ上の問題でネット上だろうとローカルだろうと外部のファイルは取れないっぽいんで base64 エンコーディングしたものを埋め込むしかないようです。
この方法については自分で調べてください。Style タグの部分にもヒントが載ってますしね。
また、原理的に元の画像のファイルサイズに対して4/3倍(≒133%)に増大するので、等倍にトリミング(425×270px)、減色など可能な限りの処理はしておくべきでしょう。
四隅は白い画像を上に被せているので角を落とさなくてOKです。(右端側が 1px 分見切れてますねw)

f:id:barrackdo:20180112005912p:image:w400
モデルとしてイラストの利用がしやすい 東北ずん子 を使ってみました。

あとは添付するだけです。

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/barrackdo/20180113/1515850893