mirror of
https://github.com/vichan-devel/vichan.git
synced 2024-11-27 17:00:52 +01:00
Add files via upload
This commit is contained in:
parent
6a53b99feb
commit
3438718667
357
inc/captcha/captcha.php
Normal file
357
inc/captcha/captcha.php
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
<?php
|
||||||
|
class CzaksCaptcha {
|
||||||
|
var $content = array();
|
||||||
|
|
||||||
|
var $width, $height, $color, $charset, $style;
|
||||||
|
|
||||||
|
function __construct($text, $left, $top, $charset=false) {
|
||||||
|
if (!$charset) {
|
||||||
|
$charset = 'abcdefghijklmnopqrstuvwxyz';
|
||||||
|
}
|
||||||
|
|
||||||
|
$len = mb_strlen($text, 'utf-8');
|
||||||
|
|
||||||
|
$this->width = $left;
|
||||||
|
$this->height = $top;
|
||||||
|
|
||||||
|
$this->charset = preg_split('//u', $charset);
|
||||||
|
|
||||||
|
$this->style = "";
|
||||||
|
|
||||||
|
for ($i = 0; $i < $len; $i++) {
|
||||||
|
$this->content[] = array(mb_substr($text, $i, 1, 'utf-8'), "top" => $top / 2 - $top / 4,
|
||||||
|
"left" => $left/10 + 9*$left*$i/10/$len,
|
||||||
|
"position" => "absolute");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->color = "hsla(".rand(1,360).", 76%, 78%, 1)";
|
||||||
|
|
||||||
|
$this->add_junk();
|
||||||
|
$this->mutate_sizes();
|
||||||
|
$this->mutate_positions();
|
||||||
|
$this->mutate_transform();
|
||||||
|
$this->mutate_anchors();
|
||||||
|
$this->randomize();
|
||||||
|
$this->mutate_containers();
|
||||||
|
$this->mutate_margins();
|
||||||
|
$this->mutate_styles();
|
||||||
|
$this->randomize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_sizes() {
|
||||||
|
foreach ($this->content as &$v) {
|
||||||
|
if (!isset ($v['font-size']))
|
||||||
|
$v['font-size'] = rand($this->height/3 - 4, $this->height/3 + 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function mutate_positions() {
|
||||||
|
foreach ($this->content as &$v) {
|
||||||
|
$v['top'] += rand(-10,10);
|
||||||
|
$v['left'] += rand(-10,10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function mutate_transform() {
|
||||||
|
$fromto = array('6'=>'9', '9'=>'6', '8'=>'8', '0'=>'0',
|
||||||
|
'z'=>'z', 's'=>'s', 'n'=>'u', 'u'=>'n',
|
||||||
|
'a'=>'ɐ', 'e'=>'ə', 'p'=>'d', 'd'=>'p',
|
||||||
|
'A'=>'∀', 'E'=>'∃', 'H'=>'H', 'o'=>'o',
|
||||||
|
'O'=>'O');
|
||||||
|
|
||||||
|
foreach ($this->content as &$v) {
|
||||||
|
$basefrom = -20;
|
||||||
|
$baseto = 20;
|
||||||
|
|
||||||
|
if (isset($fromto[$v[0]]) && rand(0,1)) {
|
||||||
|
$v[0] = $fromto[$v[0]];
|
||||||
|
$basefrom = 160;
|
||||||
|
$baseto = 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
$v['transform'] = 'rotate('.rand($basefrom,$baseto).'deg)';
|
||||||
|
$v['-ms-transform'] = 'rotate('.rand($basefrom,$baseto).'deg)';
|
||||||
|
$v['-webkit-transform'] = 'rotate('.rand($basefrom,$baseto).'deg)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function randomize(&$a = false) {
|
||||||
|
if ($a === false) {
|
||||||
|
$a = &$this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
shuffle($a);
|
||||||
|
|
||||||
|
foreach ($a as &$v) {
|
||||||
|
$this->shuffle_assoc($v);
|
||||||
|
|
||||||
|
if (is_array ($v[0])) {
|
||||||
|
$this->randomize($v[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_junk() {
|
||||||
|
$count = rand(200, 300);
|
||||||
|
|
||||||
|
while ($count--) {
|
||||||
|
$elem = array();
|
||||||
|
|
||||||
|
$elem['top'] = rand(0, $this->height);
|
||||||
|
$elem['left'] = rand(0, $this->width);
|
||||||
|
|
||||||
|
$elem['position'] = 'absolute';
|
||||||
|
|
||||||
|
$elem[0] = $this->charset[rand(0, count($this->charset)-1)];
|
||||||
|
|
||||||
|
switch($t = rand (0,9)) {
|
||||||
|
case 0:
|
||||||
|
$elem['display'] = 'none'; break;
|
||||||
|
case 1:
|
||||||
|
$elem['top'] = rand(-60, -90); break;
|
||||||
|
case 2:
|
||||||
|
$elem['left'] = rand(-40, -70); break;
|
||||||
|
case 3:
|
||||||
|
$elem['top'] = $this->height + rand(10, 60); break;
|
||||||
|
case 4:
|
||||||
|
$elem['left'] = $this->width + rand(10, 60); break;
|
||||||
|
case 5:
|
||||||
|
$elem['color'] = $this->color; break;
|
||||||
|
case 6:
|
||||||
|
$elem['visibility'] = 'hidden'; break;
|
||||||
|
case 7:
|
||||||
|
$elem['height'] = rand(0,2);
|
||||||
|
$elem['overflow'] = 'hidden'; break;
|
||||||
|
case 8:
|
||||||
|
$elem['width'] = rand(0,1);
|
||||||
|
$elem['overflow'] = 'hidden'; break;
|
||||||
|
case 9:
|
||||||
|
$elem['font-size'] = rand(2, 6); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->content[] = $elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_anchors() {
|
||||||
|
foreach ($this->content as &$elem) {
|
||||||
|
if (rand(0,1)) {
|
||||||
|
$elem['right'] = $this->width - $elem['left'] - (int)(0.5*$elem['font-size']);
|
||||||
|
unset($elem['left']);
|
||||||
|
}
|
||||||
|
if (rand(0,1)) {
|
||||||
|
$elem['bottom'] = $this->height - $elem['top'] - (int)(1.5*$elem['font-size']);
|
||||||
|
unset($elem['top']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_containers() {
|
||||||
|
for ($i = 0; $i <= 80; $i++) {
|
||||||
|
$new = [];
|
||||||
|
$new['width'] = rand(0, $this->width*2);
|
||||||
|
$new['height'] = rand(0, $this->height*2);
|
||||||
|
$new['top'] = rand(-$this->height * 2, $this->height * 2);
|
||||||
|
$new['bottom'] = $this->height - ($new['top'] + $new['height']);
|
||||||
|
$new['left'] = rand(-$this->width * 2, $this->width * 2);
|
||||||
|
$new['right'] = $this->width - ($new['left'] + $new['width']);
|
||||||
|
|
||||||
|
$new['position'] = 'absolute';
|
||||||
|
|
||||||
|
$new[0] = [];
|
||||||
|
|
||||||
|
$cnt = rand(0,10);
|
||||||
|
for ($j = 0; $j < $cnt; $j++) {
|
||||||
|
$elem = array_pop($this->content);
|
||||||
|
if (!$elem) break;
|
||||||
|
|
||||||
|
if (isset($elem['top'])) $elem['top'] -= $new['top'];
|
||||||
|
if (isset($elem['bottom'])) $elem['bottom'] -= $new['bottom'];
|
||||||
|
if (isset($elem['left'])) $elem['left'] -= $new['left'];
|
||||||
|
if (isset($elem['right'])) $elem['right'] -= $new['right'];
|
||||||
|
|
||||||
|
$new[0][] = $elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rand (0,1)) unset($new['top']);
|
||||||
|
else unset($new['bottom']);
|
||||||
|
if (rand (0,1)) unset($new['left']);
|
||||||
|
else unset($new['right']);
|
||||||
|
|
||||||
|
$this->content[] = $new;
|
||||||
|
|
||||||
|
shuffle($this->content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_margins(&$a = false) {
|
||||||
|
if ($a === false) {
|
||||||
|
$a = &$this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($a as &$v) {
|
||||||
|
$ary = ['top', 'left', 'bottom', 'right'];
|
||||||
|
shuffle($ary);
|
||||||
|
$cnt = rand(0,4);
|
||||||
|
$ary = array_slice($ary, 0, $cnt);
|
||||||
|
|
||||||
|
foreach ($ary as $prop) {
|
||||||
|
$margin = rand(-1000, 1000);
|
||||||
|
|
||||||
|
$v['margin-'.$prop] = $margin;
|
||||||
|
|
||||||
|
if (isset($v[$prop])) {
|
||||||
|
$v[$prop] -= $margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($v[0])) {
|
||||||
|
$this->mutate_margins($v[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_styles(&$a = false) {
|
||||||
|
if ($a === false) {
|
||||||
|
$a = &$this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($a as &$v) {
|
||||||
|
$content = $v[0];
|
||||||
|
unset($v[0]);
|
||||||
|
$styles = array_splice($v, 0, rand(0, 6));
|
||||||
|
$v[0] = $content;
|
||||||
|
|
||||||
|
$id_or_class = rand(0,1);
|
||||||
|
$param = $id_or_class ? "id" : "class";
|
||||||
|
$prefix = $id_or_class ? "#" : ".";
|
||||||
|
$genname = "zz-".base_convert(rand(1,999999999), 10, 36);
|
||||||
|
|
||||||
|
if ($styles || rand(0,1)) {
|
||||||
|
$this->style .= $prefix.$genname."{";
|
||||||
|
$this->style .= $this->rand_whitespace();
|
||||||
|
|
||||||
|
foreach ($styles as $k => $val) {
|
||||||
|
if (is_int($val)) {
|
||||||
|
$val = "".$val."px";
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->style .= "$k:";
|
||||||
|
$this->style .= $this->rand_whitespace();
|
||||||
|
$this->style .= "$val;";
|
||||||
|
$this->style .= $this->rand_whitespace();
|
||||||
|
}
|
||||||
|
$this->style .= "}";
|
||||||
|
$this->style .= $this->rand_whitespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
$v[$param] = $genname;
|
||||||
|
|
||||||
|
if (is_array($v[0])) {
|
||||||
|
$this->mutate_styles($v[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function to_html(&$a = false) {
|
||||||
|
$inside = true;
|
||||||
|
|
||||||
|
if ($a === false) {
|
||||||
|
if ($this->style) {
|
||||||
|
echo "<style type='text/css'>";
|
||||||
|
echo $this->style;
|
||||||
|
echo "</style>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "<div style='position: relative; width: ".$this->width."px; height: ".$this->height."px; overflow: hidden; background-color: ".$this->color."'>";
|
||||||
|
$a = &$this->content;
|
||||||
|
$inside = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($a as &$v) {
|
||||||
|
$letter = $v[0];
|
||||||
|
|
||||||
|
unset ($v[0]);
|
||||||
|
|
||||||
|
echo "<div";
|
||||||
|
echo $this->rand_whitespace(1);
|
||||||
|
|
||||||
|
if (isset ($v['id'])) {
|
||||||
|
echo "id='$v[id]'";
|
||||||
|
echo $this->rand_whitespace(1);
|
||||||
|
|
||||||
|
unset ($v['id']);
|
||||||
|
}
|
||||||
|
if (isset ($v['class'])) {
|
||||||
|
echo "class='$v[class]'";
|
||||||
|
echo $this->rand_whitespace(1);
|
||||||
|
|
||||||
|
unset ($v['class']);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "style='";
|
||||||
|
|
||||||
|
foreach ($v as $k => $val) {
|
||||||
|
if (is_int($val)) {
|
||||||
|
$val = "".$val."px";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "$k:";
|
||||||
|
echo $this->rand_whitespace();
|
||||||
|
echo "$val;";
|
||||||
|
echo $this->rand_whitespace();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "'>";
|
||||||
|
echo $this->rand_whitespace();
|
||||||
|
|
||||||
|
if (is_array ($letter)) {
|
||||||
|
$this->to_html($letter);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo $letter;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$inside) {
|
||||||
|
echo "</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function rand_whitespace($r = 0) {
|
||||||
|
switch (rand($r,4)) {
|
||||||
|
case 0:
|
||||||
|
return "";
|
||||||
|
case 1:
|
||||||
|
return "\n";
|
||||||
|
case 2:
|
||||||
|
return "\t";
|
||||||
|
case 3:
|
||||||
|
return " ";
|
||||||
|
case 4:
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function shuffle_assoc(&$array) {
|
||||||
|
$keys = array_keys($array);
|
||||||
|
|
||||||
|
shuffle($keys);
|
||||||
|
|
||||||
|
foreach($keys as $key) {
|
||||||
|
$new[$key] = $array[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
$array = $new;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//$charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789卐";
|
||||||
|
|
||||||
|
//(new CzaksCaptcha("hotwheels", 300, 80, $charset))->to_html();
|
||||||
|
?>
|
16
inc/captcha/config.php
Normal file
16
inc/captcha/config.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
// We are using a custom path here to connect to the database.
|
||||||
|
// Why? Performance reasons.
|
||||||
|
// change $pdo database_name, database_user, database_password to your own settings if not using xampp or default xampp settings:
|
||||||
|
// example $pdo = new PDO("mysql:dbname=database_name;host=localhost", "database_user", "database_password", array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
|
||||||
|
$pdo = new PDO("mysql:dbname=hokachan;host=localhost", "root", "", array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
|
||||||
|
|
||||||
|
// Captcha expiration:
|
||||||
|
$expires_in = 300; // 120 seconds
|
||||||
|
|
||||||
|
// Captcha dimensions:
|
||||||
|
$width = 250;
|
||||||
|
$height = 80;
|
||||||
|
|
||||||
|
// Captcha length:
|
||||||
|
$length = 5;
|
9
inc/captcha/dbschema.sql
Normal file
9
inc/captcha/dbschema.sql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
SET NAMES utf8;
|
||||||
|
|
||||||
|
CREATE TABLE `captchas` (
|
||||||
|
`cookie` VARCHAR(50),
|
||||||
|
`extra` VARCHAR(200),
|
||||||
|
`text` VARCHAR(255),
|
||||||
|
`created_at` INT(11),
|
||||||
|
PRIMARY KEY (cookie, extra)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
|
85
inc/captcha/entrypoint.php
Normal file
85
inc/captcha/entrypoint.php
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
$mode = @$_GET['mode'];
|
||||||
|
|
||||||
|
require_once("captcha.php");
|
||||||
|
|
||||||
|
function rand_string($length, $charset) {
|
||||||
|
$ret = "";
|
||||||
|
while ($length--) {
|
||||||
|
$ret .= mb_substr($charset, rand(0, mb_strlen($charset, 'utf-8')-1), 1, 'utf-8');
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup ($pdo, $expires_in) {
|
||||||
|
$pdo->prepare("DELETE FROM `captchas` WHERE `created_at` < ?")->execute([time() - $expires_in]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($mode) {
|
||||||
|
// Request: GET entrypoint.php?mode=get&extra=1234567890
|
||||||
|
// Response: JSON: cookie => "generatedcookie", captchahtml => "captchahtml", expires_in => 120
|
||||||
|
case "get":
|
||||||
|
if (!isset ($_GET['extra'])) {
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
header("Content-type: application/json");
|
||||||
|
|
||||||
|
$extra = $_GET['extra'];
|
||||||
|
|
||||||
|
require_once("config.php");
|
||||||
|
|
||||||
|
$text = rand_string($length, $extra);
|
||||||
|
|
||||||
|
$captcha = new CzaksCaptcha($text, $width, $height, $extra);
|
||||||
|
|
||||||
|
$cookie = rand_string(20, "abcdefghijklmnopqrstuvwxyz");
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$captcha->to_html();
|
||||||
|
$html = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
$query = $pdo->prepare("INSERT INTO `captchas` (`cookie`, `extra`, `text`, `created_at`) VALUES (?, ?, ?, ?)");
|
||||||
|
$query->execute( [$cookie, $extra, $text, time()]);
|
||||||
|
|
||||||
|
echo json_encode(["cookie" => $cookie, "captchahtml" => $html, "expires_in" => $expires_in]);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Request: GET entrypoint.php?mode=check&cookie=generatedcookie&extra=1234567890&text=captcha
|
||||||
|
// Response: 0 OR 1
|
||||||
|
case "check":
|
||||||
|
if (!isset ($_GET['mode'])
|
||||||
|
|| !isset ($_GET['cookie'])
|
||||||
|
|| !isset ($_GET['extra'])
|
||||||
|
|| !isset ($_GET['text'])) {
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once("config.php");
|
||||||
|
|
||||||
|
cleanup($pdo, $expires_in);
|
||||||
|
|
||||||
|
$query = $pdo->prepare("SELECT * FROM `captchas` WHERE `cookie` = ? AND `extra` = ?");
|
||||||
|
$query->execute([$_GET['cookie'], $_GET['extra']]);
|
||||||
|
|
||||||
|
$ary = $query->fetchAll();
|
||||||
|
|
||||||
|
if (!$ary) {
|
||||||
|
echo "0";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$query = $pdo->prepare("DELETE FROM `captchas` WHERE `cookie` = ? AND `extra` = ?");
|
||||||
|
$query->execute([$_GET['cookie'], $_GET['extra']]);
|
||||||
|
|
||||||
|
if ($ary[0]['text'] !== $_GET['text']) {
|
||||||
|
echo "0";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo "1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user