Skip to content

Instantly share code, notes, and snippets.

@kashiwasan
Created December 8, 2012 15:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kashiwasan/4240773 to your computer and use it in GitHub Desktop.
Save kashiwasan/4240773 to your computer and use it in GitHub Desktop.
モスキート音認証
<?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