Я хотел бы поделиться методом генерации изображений-инвайтов почти без бд.
К этому изобретению меня натолкнула эта статья.
Я сегодня преподал статью о генерации инвайтов, но меня сразу заминусовали и я решил убрать статью в черновики.
Программа состоит из таких файлов:
Принцип работы:
Картинка генерируется псевдослучайным способом, с некой закономерностью.
А тестер проверяет наличие этих закономерностей.
Ранее инвайт генерировался только по кодовому слову и по нему же проверялся, но как сказал devpony,
Так что так лучше.
index.php
UserID — идентификатор, чтобы если одновременно кто будет загружать изображения — чтобы не переплутились.
image.php
generator.php
Как мы видим, цвета «одинаковые», но перепутаны каналы.
test.php
Здесь подробнее.
Эти 4 цикла — тестирование осей(место «стыка четырех частей») +проверка, чтобы они были неодинаковые.
Ну, вот и все.
Правда, есть некоторые минусы.
А именно, не предусмотрено защиту от повторного использования.
Можно использовать, например, перепцетивний хэш или придумать какое-то ограничение по времени.
Я над этим еще думаю.
Демо: http://app.blastorq.pp.ua/ImgInvite/(на украинском)
GitHub: https://github.com/da411d/ImgInviteGenerator
Если нашли неточность или ошибку — пишите мне, не сильно минусуйте
К этому изобретению меня натолкнула эта статья.
Я сегодня преподал статью о генерации инвайтов, но меня сразу заминусовали и я решил убрать статью в черновики.
Программа состоит из таких файлов:
- generator.php — функция генератора
- image.php — отображает картинку
- index.php — морда
- test.php — тестер
Принцип работы:
Картинка генерируется псевдослучайным способом, с некой закономерностью.
А тестер проверяет наличие этих закономерностей.
Ранее инвайт генерировался только по кодовому слову и по нему же проверялся, но как сказал devpony,
Так что так лучше.
index.php
<?
header('Content-Type: text/html; charset=utf-8');
?>
<fieldset>
<legend>Get invite</legend>
<button onclick="document.getElementById('img').src='image.php?rand='+(Math.floor(Math.random()*999))">Обновить</button>
<br>
<br> IMG:
<img src="image.php?in=" id="img" onclick="window.open(this.src)" width="200" height="200">
<br> Кликни по картинке чтобы скачать ее.
</fieldset>
<fieldset>
<legend>Test invite</legend>
<form method="post" enctype="multipart/form-data" action="test.php">
<input type="hidden" name="UserID" value="<?php
$ip = $_SERVER['REMOTE_ADDR'];
$ua = $_SERVER['HTTP_USER_AGENT'];
$d = getdate();
$UserID = sha1($ip.$ua.$d["mday"].'Secret');
$UserID = base64_encode($UserID);
$UserID = rtrim($UserID,"=");
echo $UserID;
?>">
<input type="file" name="uploadfile" style="width:300px;height:100px;background:#fc0;">
<br>
<button type="submit">SUBMIT</button>
</form>
</fieldset>
UserID — идентификатор, чтобы если одновременно кто будет загружать изображения — чтобы не переплутились.
image.php
<?
include('generator.php');//Подключаем генератор
header('Content-Disposition: attachment; filename="image.png"');//Чтобы изображене скачивалось сразу
header ("Content-type: image/png");//Тип изображения
imagepng(generateImage());//Отдаем изображение
?>
generator.php
<?
function generateImage($str){
$secret="SECRET_STRING";
if(!isset($str)){
$str = sha1(rand(-99999,99999).$secret);//Обычно - рандом
}else{
$str = sha1($str.$secret);
}
for($i=0;$i<6*$WH+1;$i++){
$str .= sha1($str.$secret);
}
$WH = 200;//Ширина и высота
$im = imagecreatetruecolor($WH, $WH);
$im1 = imagecreatetruecolor($WH, $WH);
$im2 = imagecreatetruecolor($WH, $WH);
$im3 = imagecreatetruecolor($WH, $WH);
$im4 = imagecreatetruecolor($WH, $WH);//5 изображений
$arr = array();
for($i=0;$i<round(strlen($str)/6, 0);$i++){
$arr[] = hex2rgb(substr($str, $i*6, 6)); //Генерируем цвета
}
for ($i=0;$i<$WH/2;$i++){
$r = $arr[$i][0];
$g = $arr[$i][1];
$b = $arr[$i][2];
$color = imagecolorallocate($im, $r, $g, $b);
imagefilledrectangle($im1, $i, $i, $WH-$i, $WH-$i, $color);
$color = imagecolorallocate($im, $b, $r, $g);
imagefilledrectangle($im2, $i, $i, $WH-$i, $WH-$i, $color);
$color = imagecolorallocate($im, $g, $r, $b);
imagefilledrectangle($im3, $i, $i, $WH-$i, $WH-$i, $color);
$color = imagecolorallocate($im, $r, $b, $g);
imagefilledrectangle($im4, $i, $i, $WH-$i, $WH-$i, $color);
}
imagecopy($im, $im1, 0, 0, 0, 0, $WH/2, $WH/2);
imagecopy($im, $im2, $WH/2, 0, $WH/2, 0, $WH/2, $WH/2);
imagecopy($im, $im3, 0, $WH/2, 0, $WH/2, $WH/2, $WH/2);
imagecopy($im, $im4, $WH/2, $WH/2, $WH/2, $WH/2, $WH, $WH);
return $im;
}
function hex2rgb($hex){
$hex = str_replace("#", "", $hex);
if(strlen($hex) == 3) {
$r = hexdec(substr($hex,0,1).substr($hex,0,1));
$g = hexdec(substr($hex,1,1).substr($hex,1,1));
$b = hexdec(substr($hex,2,1).substr($hex,2,1));
} else {
$r = hexdec(substr($hex,0,2));
$g = hexdec(substr($hex,2,2));
$b = hexdec(substr($hex,4,2));
}
$rgb = array($r, $g, $b);
return $rgb;
}
Как мы видим, цвета «одинаковые», но перепутаны каналы.
test.php
<?php
error_reporting(0);
include('generator.php');
$UserID = rtrim(base64_encode(sha1($_POST['UserID'])), '=');
$name1 = './files/image1_'.$UserID.'.png';
if (copy($_FILES['uploadfile']['tmp_name'], $name1)){
$im = imagecreatefrompng($name1);
function getColor($im, $x, $y){
$rgb = imagecolorat($im, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
return array($r, $g, $b);
}
$max_count = 0;
$counted = 0;
for($i=0;$i<100;$i++){
$max_count++;
if(
getColor($im, 99, $i)[0] == getColor($im, 100, $i)[1] AND
getColor($im, 99, $i)[1] == getColor($im, 100, $i)[2] AND
getColor($im, 99, $i)[2] == getColor($im, 100, $i)[0] AND
(getColor($im, 99, $i)[0] != getColor($im, 100, $i)[0] OR
getColor($im, 99, $i)[1] != getColor($im, 100, $i)[1] OR
getColor($im, 99, $i)[2] != getColor($im, 100, $i)[2])){
$counted++;
}
}
for($i=0;$i<100;$i++){
$max_count++;
if(
getColor($im, $i, 99)[0] == getColor($im, $i, 100)[1] AND
getColor($im, $i, 99)[1] == getColor($im, $i, 100)[0] AND
getColor($im, $i, 99)[2] == getColor($im, $i, 100)[2] AND
(getColor($im, $i, 99)[0] != getColor($im, $i, 100)[0] OR
getColor($im, $i, 99)[1] != getColor($im, $i, 100)[1] OR
getColor($im, $i, 99)[2] != getColor($im, $i, 100)[2])){
$counted++;
}
}
for($i=101;$i<200;$i++){
$max_count++;
if(
getColor($im, $i, 99)[0] == getColor($im, $i, 100)[1] AND
getColor($im, $i, 99)[1] == getColor($im, $i, 100)[0] AND
getColor($im, $i, 99)[2] == getColor($im, $i, 100)[2] AND
(getColor($im, $i, 99)[0] != getColor($im, $i, 100)[0] OR
getColor($im, $i, 99)[1] != getColor($im, $i, 100)[1] OR
getColor($im, $i, 99)[2] != getColor($im, $i, 100)[2])){
$counted++;
}
}
for($i=101;$i<200;$i++){
$max_count++;
if(
getColor($im, 99, $i)[0] == getColor($im, 100, $i)[2] AND
getColor($im, 99, $i)[1] == getColor($im, 100, $i)[0] AND
getColor($im, 99, $i)[2] == getColor($im, 100, $i)[1] AND
(getColor($im, 99, $i)[0] != getColor($im, 100, $i)[0] OR
getColor($im, 99, $i)[1] != getColor($im, 100, $i)[1] OR
getColor($im, 99, $i)[2] != getColor($im, 100, $i)[2])){
$counted++;
}
}
if($counted>$max_count*0.9){//Если больше 90%
echo " COMPLETE";
}else{
echo " FAILED";
}
}else{
echo "ERROR ".$_FILES['uploadfile']['error'];
}
?>
Здесь подробнее.
Эти 4 цикла — тестирование осей(место «стыка четырех частей») +проверка, чтобы они были неодинаковые.
Ну, вот и все.
Правда, есть некоторые минусы.
А именно, не предусмотрено защиту от повторного использования.
Можно использовать, например, перепцетивний хэш или придумать какое-то ограничение по времени.
Я над этим еще думаю.
Демо: http://app.blastorq.pp.ua/ImgInvite/(на украинском)
GitHub: https://github.com/da411d/ImgInviteGenerator
Если нашли неточность или ошибку — пишите мне, не сильно минусуйте
Only registered users can participate in poll. Log in, please.
Как вам?
18.23% +35
32.29% ±62
49.48% -95
192 users voted. 142 users abstained.