Created
December 8, 2012 15:39
-
-
Save kashiwasan/4240773 to your computer and use it in GitHub Desktop.
モスキート音認証
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// モスキート音認証 | |
// バージョン 1.1 | |
// 作者: 園田 裕大 | |
// 柏木 祥太 | |
// サイト: http://www.0319.jp/ | |
// ライセンス: PHP License | |
// This product includes PHP, freely available from http://www.php.net/ | |
/////////////// 定義 //////////////// | |
// サンプリングレート | |
define("SAMPLERATE", 95000); | |
define("TWOPI", 2 * M_PI); | |
// 一字の感覚 | |
define("CW_SPEED", 10); | |
// モールス符号の周波数 | |
define("CW_TONE", 19000); | |
// モールス符号置き換えテーブル | |
$CWCODE = array('A'=>'01','B'=>'1000','C'=>'1010','D'=>'100','E'=>'0', | |
'F'=>'0010','G'=>'110','H'=>'0000','I'=>'00','J'=>'0111', | |
'K'=>'101','L'=>'0100','M'=>'11','N'=>'10', 'O'=>'111', | |
'P'=>'0110','Q'=>'1101','R'=>'010','S'=>'000','T'=>'1', | |
'U'=>'001','V'=>'0001','W'=>'011','X'=>'1001','Y'=>'1011', | |
'Z'=>'1100', '0'=>'11111','1'=>'01111','2'=>'00111', | |
'3'=>'00011','4'=>'00001','5'=>'00000','6'=>'10000', | |
'7'=>'11000','8'=>'11100','9'=>'11110'); | |
//////////// 定義ここまで //////////// | |
// セッション開始 | |
session_start(); | |
// 変数初期化 | |
$succcess = false; | |
// 失敗回数超過処理 | |
if ($_COOKIE['misstry'] == 'over' || $_SESSION['misstry'] >= 3) { | |
$error['input'] = 'over'; | |
$expire = time() + 24 * 3600; | |
setcookie('misstry', 'over', $expire, '', $_SERVER['HTTP_HOST']); | |
} | |
// 認証処理 | |
if (!empty($_POST)) { | |
if ($_POST['input'] == '') { | |
// 空欄フラグ | |
$error['input'] = 'empty'; | |
} else { | |
if ($_POST['input'] != $_SESSION['rand']) { | |
// 失敗フラグ | |
$error['input'] = 'mistake'; | |
// 失敗回数加算 | |
++$_SESSION['misstry']; | |
} | |
} | |
if (empty($error)) { | |
// 失敗回数リセット | |
$_SESSION['misstry'] = 0; | |
// 完了フラグ | |
$success = true; | |
} | |
} | |
// ランダムな文字列を生成 | |
function randomstring($lengthrequired = 8){ | |
$charlist = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; | |
mt_srand(); | |
$res = ''; | |
for($i = 0; $i < $lengthrequired; $i++) | |
{ | |
$res .= $charlist[mt_rand(0, strlen($charlist) - 1)]; | |
} | |
return $res; | |
} | |
$_SESSION['rand'] = randomstring(); | |
// 実験用特定文字列指定 | |
// if (!empty($_GET['rand'])) { | |
// $_SESSION['rand'] = $_GET['rand']; | |
// } | |
$ToneTime = 1.0/CW_TONE; | |
// モールス符号の速度 | |
$DitTime = 1.145/5.0; | |
$ncharspc = 122.5/CW_SPEED; | |
// 矩形波生成用設定 | |
$nwordspc = floor(2*$ncharspc + 0.5); | |
$DahTime = 3*$DitTime; | |
$sampleDT = 1.0/SAMPLERATE; | |
$Phase = 0; | |
$DPhase = 0; | |
$slash = false; | |
// 矩形波生成用関数定義 | |
function OscReset () { | |
global $sampleDT, $ToneTime, $Phase, $DPhase; | |
$Phase = 0; | |
$DPhase = TWOPI*$sampleDT/$ToneTime; | |
} | |
function Osc () { | |
global $Phase, $DPhase; | |
$Phase += $DPhase; | |
if ($Phase >= TWOPI) { | |
$Phase -= TWOPI; | |
} | |
return sin($Phase); | |
} | |
// 矩形波生成 | |
OscReset(); | |
$dt = 0; | |
$ditstr = ''; | |
$dahstr = ''; | |
$spcstr = ''; | |
while ($dt < $DitTime) { | |
$x = Osc(); | |
if ($dt < (0.5*$DitTime)) { | |
$x = $x*sin((M_PI/2.0)*$dt/(0.5*$DitTime)); | |
$ditstr .= chr(floor(120*$x+128)); | |
$dahstr .= chr(floor(120*$x+128)); | |
} else if ($dt > (0.5*$DitTime)) { | |
$dahstr .= chr(floor(120*$x+128)); | |
$x = $x*sin((M_PI/2.0)*($DitTime-$dt)/(0.5*$DitTime)); | |
$ditstr .= chr(floor(120*$x+128)); | |
} else { | |
$ditstr .= chr(floor(120*$x+128)); | |
$dahstr .= chr(floor(120*$x+128)); | |
} | |
$spcstr .= chr(128); | |
$dt += $sampleDT; | |
} | |
$dt = 0; | |
while ($dt < $DitTime) { | |
$x = Osc(); | |
$dahstr .= chr(floor(120*$x+128)); | |
$dt += $sampleDT; | |
} | |
$dt = 0; | |
while ($dt < $DitTime) { | |
$x = Osc(); | |
if ($dt > (0.5*$DitTime)) { | |
$x = $x*sin((M_PI/2.0)*($DitTime-$dt)/(0.5*$DitTime)); | |
$dahstr .= chr(floor(120*$x+128)); | |
} else { | |
$dahstr .= chr(floor(120*$x+128)); | |
} | |
$dt += $sampleDT; | |
} | |
$_SESSION['rand'] = strtoupper($_SESSION['rand']); | |
$soundstr = ''; | |
for ($i = 0; $i < strlen($_SESSION['rand']); $i++) { | |
if ($_SESSION['rand'][$i] == ' ') { | |
for ($j = 0; $j < $nwordspc; $j++) { | |
$soundstr .= $spcstr; | |
} | |
} else if (array_key_exists($_SESSION['rand'][$i], $CWCODE)) { | |
$xchar = $CWCODE[$_SESSION['rand'][$i]]; | |
for ($k = 0; $k < strlen($xchar); $k++) { | |
if ($xchar[$k] == '0') { | |
$soundstr .= $ditstr; | |
} else { | |
$soundstr .= $dahstr; | |
} | |
$soundstr .= $spcstr; | |
} | |
for ($j = 1; $j < $ncharspc; $j++) { | |
$soundstr .= $spcstr; | |
} | |
} | |
} | |
$n = strlen($soundstr); | |
for ($i = 0; $i<$n; $i++) { | |
$x = Ord($soundstr[$i]); | |
} | |
$x = $n + 32; | |
$NSizeStr = ''; | |
for ($i=0; $i<4; $i++) { | |
$tmp = $x % 256; | |
$NSizeStr .= chr($x % 256); | |
$x = floor($x/256); | |
} | |
$riffstr = 'RIFF'.$NSizeStr.'WAVE'; | |
$x = SAMPLERATE; | |
$SampRateStr = ''; | |
for ($i=0; $i<4; $i++) { | |
$SampRateStr .= chr($x % 256); | |
$x = floor($x/256); | |
} | |
$fmtstr = 'fmt '.chr(16).chr(0).chr(0).chr(0).chr(1).chr(0).chr(1).chr(0) | |
.$SampRateStr.$SampRateStr.chr(1).chr(0).chr(8).chr(0); | |
$x = $n; | |
$NSampStr = ''; | |
for ($i=0; $i<4; $i++) { | |
$NSampStr .= chr($x % 256); | |
$x = floor($x/256); | |
} | |
// base64エンコード | |
$soundstr = 'data'.$NSampStr.$soundstr; | |
$output = base64_encode($riffstr.$fmtstr.$soundstr); | |
?> | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>モスキート音認証</title> | |
<audio id="audio" src="data:audio/wav;base64,<?php echo $output; ?>" preload="auto"></audio> | |
</head> | |
<body> | |
<h1>モスキート音認証<small> バージョン1.1β</small></h1> | |
<?php if ($success == false && empty($error)): ?> | |
<h2>使い方</h2> | |
<p>まずは、筆記用具(メモ用紙も含める)を用意。</p> | |
<p>次に、スピーカーの音量を適当に調節し、下記「サウンドを再生」ボタンを押下。</p> | |
<p>とても高い・(ピ)と-(ピー)の二種類の音(20歳以上の人間には聞こえにくいか、全く聞こえない)が聞こえるので、記号を使ってメモ。</p> | |
<p>うまくメモを取れたら、下記の「モールスキーボード」に記号で打ち込む。</p> | |
<p>音質のよいスピーカーでサウンドを聞くと良い。</p> | |
<p>3回以上失敗すると24時間後まで再認証できない。</p> | |
<h2>サウンドコントローラー</h2> | |
<input type="button" value="サウンドを再生" onclick="audio.play();"> | |
<input type="button" value="サウンドを一時停止" onclick="audio.pause();"> | |
<input type="button" value="サウンドを停止" onclick="if(!audio.ended){ audio.pause(); audio.currentTime = 0; }"> | |
<h2>モールスキーボード</h2> | |
<form method="post" enctype="multipart/form-data"> | |
<input type="button" value="・-" onClick="input.value = input.value + 'A';"> | |
<input type="button" value="-・・・" onClick="input.value = input.value + 'B';"> | |
<input type="button" value="-・-・" onClick="input.value = input.value + 'C';"> | |
<input type="button" value="-・・" onClick="input.value = input.value + 'D';"> | |
<input type="button" value="・" onClick="input.value = input.value + 'E';"> | |
<input type="button" value="・・-・" onClick="input.value = input.value + 'F';"> | |
<input type="button" value="--・" onClick="input.value = input.value + 'G';"> | |
<br> | |
<input type="button" value="・・・・" onClick="input.value = input.value + 'H';"> | |
<input type="button" value="・・" onClick="input.value = input.value + 'I';"> | |
<input type="button" value="・---" onClick="input.value = input.value + 'J';"> | |
<input type="button" value="-・-" onClick="input.value = input.value + 'K';"> | |
<input type="button" value="・-・・" onClick="input.value = input.value + 'L';"> | |
<input type="button" value="--" onClick="input.value = input.value + 'M';"> | |
<input type="button" value="-・" onClick="input.value = input.value + 'N';"> | |
<br> | |
<input type="button" value="---" onClick="input.value = input.value + 'O';"> | |
<input type="button" value="・--・" onClick="input.value = input.value + 'P';"> | |
<input type="button" value="--・-" onClick="input.value = input.value + 'Q';"> | |
<input type="button" value="・-・" onClick="input.value = input.value + 'R';"> | |
<input type="button" value="・・・" onClick="input.value = input.value + 'S';"> | |
<input type="button" value="-" onClick="input.value = input.value + 'T';"> | |
<input type="button" value="・・-" onClick="input.value = input.value + 'U';"> | |
<br> | |
<input type="button" value="・・・-" onClick="input.value = input.value + 'V';"> | |
<input type="button" value="・--" onClick="input.value = input.value + 'W';"> | |
<input type="button" value="-・・-" onClick="input.value = input.value + 'X';"> | |
<input type="button" value="-・--" onClick="input.value = input.value + 'Y';"> | |
<input type="button" value="--・・" onClick="input.value = input.value + 'Z';"> | |
<br> | |
<br> | |
<input type="button" value="・----" onClick="input.value = input.value + '1';"> | |
<input type="button" value="・・---" onClick="input.value = input.value + '2';"> | |
<input type="button" value="・・・--" onClick="input.value = input.value + '3';"> | |
<input type="button" value="・・・・-" onClick="input.value = input.value + '4';"> | |
<input type="button" value="・・・・・" onClick="input.value = input.value + '5';"> | |
<br> | |
<input type="button" value="-・・・・" onClick="input.value = input.value + '6';"> | |
<input type="button" value="--・・・" onClick="input.value = input.value + '7';"> | |
<input type="button" value="---・・" onClick="input.value = input.value + '8';"> | |
<input type="button" value="----・" onClick="input.value = input.value + '9';"> | |
<input type="button" value="-----" onClick="input.value = input.value + '0';"> | |
<br> | |
認証コード: <input type="text" maxlength="8" size="15" name="input"><input type="submit" value="認証"><input type="button" value="クリア" onClick="input.value = '';"> | |
</form> | |
<?php endif; ?> | |
<?php if ($error['input'] == 'empty'): ?> | |
<h2>認証コードが空</h2> | |
<p>認証コードが空です。</p> | |
<?php endif; ?> | |
<?php if ($error['input'] == 'mistake'): ?> | |
<h2>認証失敗</h2> | |
<p>認証コードが間違っています。</p> | |
<h2>失敗回数</h2> | |
<?php echo $_SESSION['misstry']; ?>/3回</p> | |
<?php endif; ?> | |
<?php if ($error['input'] == 'over'): ?> | |
<h2>回数超過</h2> | |
<p>認証失敗の回数が3回を超えました。</p> | |
<?php endif; ?> | |
<?php if ($success == true): ?> | |
<h2>認証成功</h2> | |
<p>おめでとうございます。</p> | |
<p>認証に成功しました。</p> | |
<?php endif; ?> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment