<?php $t = strtotime("2018-1-1"); $t = month_add($t, 3); echo date('Y-m-d', $t)."\n"; function month_add($t, $n){ $year = date('Y', $t); $month = (int)date('m', $t); $mm = [1=>31, 2=>28, 3=>31, 4=>30, 5=>31, 6=>30, 7=>31, 8=>31, 9=>30, 10=>31, 11=>30, 12=>31]; $isleap = ($year%4)==0 && ($year%100)!=0 || ($year%400)==0; $mm[2] = $isleap ? 29 :28; // nヶ月後の日数計算 $days = 0; for ($i = 0; $i < $n; $i++){ $m = $month + $i; $m = ($m > 12) ? $m - 12 : $m; $days += $mm[$m]; } $DAY_SEC = 60 * 60 * 24; return $t + ($days + $DAY_SEC); }
Month: August 2016
再帰を使わずに中置記法
<?php $str = "(1 + 2) * 3"; $res = calc_str2($str); echo $res."\n"; function calc_str2($str){ $stack = []; $polish = []; while ($str != ""){ $t = get($str); if ($t == '(') { $stack[] = $t; continue; } if ($t == ')') { while (count($stack) > 0){ $s_top = array_pop($stack); if ($s_top == '(') break; $polish[] = $s_top; } continue; } while (count($stack) > 0){ $s_top = $stack[count($stack)-1]; if(priority($t) > priority($s_top)) break; $polish[] = array_pop($stack); } $stack[] = $t; } while(count($stack) > 0) $polish[] = array_pop($stack); echo "[".implode(" ", $polish)."]\n"; foreach ($polish as $t){ if (preg_match('#^\d+$#', $t)){ $tack[] = intval($t); continue; } $b = array_pop($stack); $a = array_pop($stack); switch ($t){ case '+': $c = $a + $b; break; case '-': $c = $a - $b; break; case '*': $c = $a * $b; break; case '/': $c = $a / $b; break; default: throw new Exception("未知の文字:$t"); } $stack[] = $c; } return array_pop($stack); } function priority($c){ $pri = ['num'=>3, '*'=>2, '/'=>2, '+'=>1, '-'=>1, '('=>0]; return isset($pri[$c]) ? $pri[$c] : $pri['num']; } function get(&$str){ $str = trim($str); $c = substr($str, 0, 1); if (strpos("()+-*/", $c) !== false){ $str = substr($str, 1); return $c; } if (preg_match('#^(\d+)#', $str, $m)){ $str = substr($str, strlen($m[1])); return $m[1]; } throw new Exception("未知の文字: $c"); }
中置記法の計算方法
<?php $str = "1 + 2 * 3"; $res = calc_str($str); echo $res."\n"; function calc_str($str){ $stack = []; $polish = []; while ($str != "") { $t = get($str); while (count($stack) > 0){ $s_top = $stack[count($stack)-1]; if (priority($t) > priority($s_top))break; $polish[] = array_pop($stack); } $stack[] = $t; } while (count($stack) > 0) $polish[] = array_pop($stack); echo "[".implode(" ", $polish)."]\n"; foreach ($polish as $t){ if (preg_match('#^\d+$#', $t)){ $stack[] = intval($t); continue; } $b = array_pop($stack); $a = array_pop($stack); switch ($t) { case '+': $c = $a + $b; break; case '-': $c = $a - $b; break; case '*': $c = $a * $b; break; case '/': $c = $a / $b; break; default: throw new Exception("未知の文字:$t"); } $stack[] = $c; } return array_pop($stack); } function priority($c) { $pri = ['num'=>3, '*'=>2, '/'=>2, '+'=>1, '-'=>1]; return isset($pri[$c]) ? $pri[$c] : $pri['num']; } function get(&$str) { $str = trim($str); $c = substr($str, 0, 1); if (strpos("+-*/", $c) !== false){ $str = substr($str, 1); return $c; } if (preg_match('#^(\d+)#', $str, $m)){ $str = substr ($str, strlen($m[1])); return $m[1]; } throw new Exception("未知の文字: $c"); }
中置記法の計算方法
<?php // check input $inp = isset($_GET["inp"]) ? $_GET["inp"] : "(1+2)*(3+4)"; // calculate $answer = calcInfix($inp); // calculate function calcInfix($str){ global $input_str; $input_str = $str; // main transaction return plus_minus(); } // add, minus function plus_minus() { $v = mul_div(); while(peek() == "+" || peek() == "-"){ $op = get(); if ($op == "+") $v += mul_div(); if ($op == "-") $v -= mul_div(); } return $v; } function mul_div(){ $v = paren(); while(peek() == "*" || peek() == "/"){ $op = get(); if ($op == "*") $v *= paren(); if ($op == "/") $v /= paren(); } return $v; } function paren(){ $v = get(); if ($v == '(') { $v = plus_minus(); $t = get(); if ($t != ")") throw new Exception("カッコ未対応"); } return $v; } function get(){ global $input_str; $input_str = ltrim($input_str); $c = substr($input_str, 0, 1); if (strpos("+-*/()", $c) !== false){ $input_str = substr($input_str, 1); return $c; } if (preg_match('#^([0-9]+)#', $input_str, $m)){ $input_str = substr($input_str, strlen($m[1])); return intval($m[1]); } } function unget($t){ global $input_str; $input_str = $t . $input_str; } function peek(){ $c = get(); unget($c); return $c; } $inp_ = htmlentities($inp, ENT_QUOTES); echo <<< EOS <!DOCTYPE html><meta charset="UTF-8"> <form> 式:<input name="inp" value="inp_" size="30"> <input type="submit" value="calculate"> </form><hr> <div>答え: $answer</div> EOS;
逆ポーランド電卓
<?php //入力をチェック $rpn = isset($_GET["rpn"]) ? $_GET["rpn"] : "1 2 3 * +"; // calculate RPN $history = ""; $answer = calcRPN($rpn); // calculate RPN function calcRPN($str){ global $history; $tokens = preg_split('#\s+#', trim($str)); $stack = []; foreach ($tokens as $t){ if (preg_match('#\s+#', trim($str)); $stack =[]; foreach ($token as $t){ if (preg_match('#^[0-9\.]+$#', $t)){ $stack[] = floatval($t); addHistory($stack, "$t: push"); continue; } $b = array_pop($stack); $a = array_pop($stack); switch ($t){ case '+': $c = ($a + $b); break; case '-': $c = ($a - $b); break; case '*': $c = ($a * $b); break; case '/': $c = ($a / $b); break; case '%': $c = ($a % $b); break; default: return "error"; } $stack[] = $c; addHistory($stack, "$t: pop $a $b, push $c"); } return array_pop($stack); } function addHistory($stack, $desc){ global $history; $line = "<td>$desc</td>". "<td>[".implode(", ", $stack)."]</td>"; $history .= "<tr>".$line."</tr>"; } // input HTML form $rpn_ = htmltities($rpn, ENT_QUOTES); echo <<< EOS <!DOCTYPE html><meta charset="UTF-8"> <form> RPN: <input name="rpn" value="$rpn_" size="30"><br> <input type="submit" value="計算"> </form><hr> <div>答え: $answer</div><hr> <table><tr><td>操作</td><td>スタック</td></tr> $history</table> EOS;
ユーザー認証
<?php $admin_password = "m9k7PZRgG8SAySmG"; $dataFile = dirname(__FILE__).'/data/userauth.data'; $iv_a = [177,108,37,2,26,148,178,3,72,100,27,156,62,231,205,83]; $enc_iv = implode('', array_map('chr', $iv_a)); $info = ""; $m = empty($_POST['m']) ? '' : $_POST['m']; if($m == 'add') $info = m_add(); if($m == 'get') $info = m_get(); function m_add() { $userId = empty($_POST['userId']) ? '' $_POST['userId']; $password = empty($_POST['password']) ? '' : $_POST['password']; $secret = empty($_POST['secret']) ? '' : $_POST['secret']; if ($userId == "" || $password == "" || $secret == ""){ return "ユーザー情報を正しく入力してください"; } putUserData([ 'userId'=>$userId, 'password'=>$password, 'secret'=>$secret]); return "保存しました"; } //ユーザーデータを追加 ---(*3) function putUserData($user){ global $dataFile, $enc_iv, $admin_password; $salt = base64_encode(openssl_random_pseudo_bytes(16)); $password = $user['password']; $user['password'] = hash('sha256', $password.$salt); $user['salt'] = $salt; $secret = openssl_encrypt( $user['secret'], 'aes-256-cbc', $password.$salt, 0, $enc_iv); $user['secret']= $secret; $data = getUserData(); $data[$user['userId']] = $user; $json = json_encode($data); print_r($data, $json); $enc = openssl_encrypt($json, 'aes-256-cbc', $admin_password, 0, $enc_iv); file_put_contents($dataFile, $enc); } // user transaction function m_get(){ global $enc_iv; $userId = empty($_POST['userId']) ? '' : $_POST['userId']; $password = empty($_POST['password']) ? '' : $_POST['password']; if ($userId == "")return "input is empty"; $data = getUserData(); if (!isset($data[$userId])) return "情報に誤りがあります"; $u = $data[$userId]; $salt = $u['salt']; $pw_hash = hash('sha256', $password.$salt); if ($u['password'] != $pw_hash) return "情報にあやまりがあります"; $secret_raw = $u['secret']; $secret = openssl_decrypt($secret_raw, "aes-256-cbc", $password.$salt, 0, $enc_iv); $secret_ = htmlentities($secret); return "<div class='read'><h3>ユーザー認証成功</h3>". "<ul><li>userId: $userId</li>". "<li>secret: $secret_</li></ul></div>"; } // get user data function getUserData(){ global $dataFile, $enc_iv, $admin_password; $data = []; if (file_exists($dataFile)){ $raw = file_get_contents($dataFile); $json = openssl_decrypt($raw, "aes-256-cbc", $admin_password, 0, $enc_iv); $data = json_decode($json, true); } return $data; } ?> <html><meta charset="utf-8"> <body><style> .read { background-color: #e0e0fc; padding: 10px; } form { margin-left: 10px; } </style> <?php echo $info; ?> <h2>ユーザーの参照</h2> <form method="post"> <input type="hidden" name="m" value="get"> userId:<br><input name="userId"><br> password:<br><input type="password" name="password"><br> <input type="submit" value="参照"> </form> <hr><h2>ユーザーの追加</h2> <form method="post"> <input type="hidden" name="m" value="add"> userId:<br><input name="userId"><br> password:<br><input type="password" name="password"><br> secret(秘密のメモ):<br><input name="secret"><br> <input type="submit" value="add"> </form> </body></html>
OPEN SSL
シーザー暗号の解読
シーザー暗号
<meta charset="UTF-8"> <?php // get parameter $str = isset($_GET["str"]) : ""; $shift = isset($_GET["shift"]) ? intval($_GET["shift"]) : 3; if ($str != "")convert($str, $shift); $str_ = htmlentities($str, ENT_QUOTES); // display form echo <<< EOS <form> character line: <input name="str" value="$str_"><br> shift: <input name="shift" value="$shift"><br> <input type=="submit" value="change"> </form> EOS; function makeTable($shift){ $ch1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $shift = $shift % strlen($ch1); $ch2 = substr($ch1, $shift).substr($ch1, 0, $shift); $table = []; for ($i = 0; $i < strlen($ch1); $i++){ $c1 = substr($ch1, $i, 1); $c2 = substr($ch2, $i, 1); $table[$c2] = $c1; } return $table; } function convert($str, $shift){ if (empty($_GET["str"])) return; $table = makeTable($shift); $res = ""; for ($i = 0; $i < strlen($str); $i++){ $c = substr($str, $i, 1); $res .= isset($table[$c]) ? $table[$c] : $c; } $str = htmlentities($str, ENT_QUOTES); $res = htmlentities($res, ENT_QUOTES); echo "<div>before transfer: $str</div>"; echo "<div>after transfer: $res</div><hr>"; }
迷路の自動生成
0,";
$pat[1] = "1,";
$html = "";
for ($y = 0; $y < count($maze); $y++){ for ($x = 0; $x < count($maze); $x++){ $html .= $pat[$maze[$y][$x]]; } $html .= "\n"; } return $html; }[/php]