English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In fact, image recognition technology is not very different from what we usually do with password verification and the like, both of which require storing the data to be verified in advance, and then comparing the entered (recognized) data with the data in the database when used. The only difference is that image recognition technology has a certain degree of tolerance, while our usual password verification has to100% match.
A few days ago, a friend mentioned making a game click lottery, recognizing text in the image, and I immediately thought of js control or flash mask layer, feeling that this method is the most convenient, quick and effective, and saves server resources, but the requirements proposed by the other side were to recognize text in the image through php.
By the way, the news those two days was:1, Alibaba's face recognition payment;2,12306A new captcha is used, saying that now all domestic ticket抢票 software can't be used, it was cracked within a day of release. Then it was quite coincidental that I read an article about Java image recognition technology that morning. So I thought about looking at PHP image recognition technology.
In fact, the so-called image recognition is not a new technology, at least the information I found is very early. It's just that I haven't been involved in this kind of work, so I haven't seen it.
First let's talk about the requirements for this experiment: there is an image with three positions, each with three numbers. The task is to extract the value of the number at the corresponding position. (Shrewd students might notice that the following code is copied from someone else, indeed, it is, I directly copied and deleted it, because I am just scratching the surface of this, and the original code of the author will be attached at the end).
class gjPhone { protected $imgPath; // Image path protected $imgSize; // Image size protected $hecData; // The array after separation protected $horData; // Data organized horizontally Protected $verData; // Data organized vertically Function __construct ($path) { $this->imgPath = $path; } Public function getHec () { $size = getimagesize($this->imgPath); $res = imagecreatefrompng($this->imgPath); For ($i = 0; $i < $size[1]; ++ $i) { For ($j = 0; $j < $size[0]; ++ $j) { $rgb = imagecolorat($res, $j, $i); $rgbarray = imagecolorsforindex($res, $rgb); If ($rgbarray['red'] < 125 || $rgbarray['green'] < 125 || $rgbarray['blue'] < 125) { $data[$i][$j] = 1; } else { $data[$i][$j] = 0; } } } $this->imgSize = $size; $this->hecData = $data; } Public function magHorData () { $data = $this->hecData; $size = $this->imgSize; $z = 0; For ($i = 0; $i < $size[1]; ++ $i) { If (in_array('1', $data[$i])) { $z ++; For ($j = 0; $j < $size[0]; ++ $j) { If ($data[$i][$j] == '1') { $newdata[$z][$j] = 1; } else { $newdata[$z][$j] = 0; } } } } return $this->horData = $newdata; } public function showPhone ($ndatas) { error_reporting(0); $phone = null; $d = 0; foreach ($ndatas as $key => $val) { if (in_array(1, $val)) { foreach ($val as $k => $v) { $ndArr[$d] .= $v; } } if (! in_array(1, $val)) { $d ++; } } foreach ($ndArr as $key01 => $val01) { $phone .= $this->initData($val01); } return $phone; } /** * Initial data */ public function initData ($numStr) { $result = null; $data = array( '1=> '00000000'111000000000000001110000000001001000100000000010100011000000000011000110000000000110000100000000010110011000000', '5=> '0000000000'1000000000000000010000000000100100100000000000101001110000000000100000110000000011000000100000001101000010000', '10=> '000000'11100011100000000011001100100100100010010001000110000100100010001100001001000100011000010010001001001001100010100' ); foreach ($data as $key => $val) { similar_text($numStr, $val, $pre);}} if ($pre > 95) { // Similarity95% above $result = $key; break; } } return $result; } } $imgurl = 'jd.png'; list ($width, $height, $type, $attr) = getimagesize($imgurl); $new_w = 17; $new_h = 11; $thisimage = imagecreatetruecolor($new_w, $new_h); // $new_w, $new_h as the width and height of the cropped image $background = imagecolorallocate($thisimage, 255, 255, 255); imagefilledrectangle($thisimage, 0, 0, $new_w, $new_h, $background); $oldimg = imagecreatefrompng($imgurl); // Load the original image // Firstly, locate the position to take the image (here you can use frontend js or other means to locate, since this is a test, I used ps to locate and hard-coded it) $weizhi = array( '1' => 165, '5' => 308, '10' => 456 ); foreach ($weizhi as $wwzz) { $src_y = 108; imagecopy($thisimage, $oldimg, 0, 0, $wwzz, $src_y, $new_w, $new_h); // $src_y,$new_w are the coordinates of the upper left corner of the cropped area in the original image, copying a part of the image src_im from the coordinates src_x, src_y, width src_w, height src_h to the position dst_x and dst_y in the dst_im image. $tem_png = 'tem_1.png'; imagepng($thisimage, __DIR__ .'/'. $tem_png); // Copy the desired recognition position from the original image by positioning and generate a new cache image for later use by the image recognition class. $gjPhone = new gjPhone($tem_png); // Instantiate the class $gjPhone->getHec(); // Separating the image pixels $horData = $gjPhone->magHorData(); // Converting the separated data into 01represents the image, here you can set it according to your preference $phone = $gjPhone->showPhone($horData); // Converting the 01Matching the data with the data in the database, matching degree95The above is successful, and the array here is written directly due to the test nature of the project echo '| ' . $phone . ' | '; }
So it seems that actually12306It is understandable that the captcha can be cracked, and there is no need to criticize it so harshly. Just keep capturing captcha images and converting them into data readable by your program and storing them in the database, and then matching them when verifying.
I saw an Alipay captcha form recently, and at first I thought it might be better, but now it seems that as long as one is determined, it can actually be cracked.
Alright, here is the original code.
/** * phone number recognition. * @author by zsc for 2010.03.24 */ class gjPhone { protected $imgPath; // Image path protected $imgSize; // Image size protected $hecData; // The array after separation protected $horData; // Data organized horizontally Protected $verData; // Data organized vertically Function __construct ($path) { $this->imgPath = $path; } /** * Color separation conversion... * * @param unknown_type $path * @return unknown */ Public function getHec () { $size = getimagesize($this->imgPath); $res = imagecreatefrompng($this->imgPath); For ($i = 0; $i < $size[1]; ++ $i) { For ($j = 0; $j < $size[0]; ++ $j) { $rgb = imagecolorat($res, $j, $i); $rgbarray = imagecolorsforindex($res, $rgb); If ($rgbarray['red'] < 125 || $rgbarray['green'] < 125 || $rgbarray['blue'] < 125) { $data[$i][$j] = 1; } else { $data[$i][$j] = 0; } } } $this->imgSize = $size; $this->hecData = $data; } /** * Data organized horizontally after color separation... * * @return unknown */ Public function magHorData () { $data = $this->hecData; $size = $this->imgSize; $z = 0; For ($i = 0; $i < $size[1]; ++ $i) { If (in_array('1', $data[$i])) { $z ++; For ($j = 0; $j < $size[0]; ++ $j) { If ($data[$i][$j] == '1') { $newdata[$z][$j] = 1; } else { $newdata[$z][$j] = 0; } } } } return $this->horData = $newdata; } /** * Organize longitudinal data... * * @return unknown */ Public function magVerData ($newdata) { For ($i = 0; $i < 132; ++ $i) { For ($j = 1; $j < 13; ++ $j) { $ndata[$i][$j] = $newdata[$j][$i]; } } $sum = count($ndata); $c = 0; For ($a = 0; $a < $sum; ++) { $value = $ndata[$a]; if (in_array(1Comma, $value) $ndatas[$c] = $value; $c ++; } elseif (is_array($ndatas)) { $b = $c - 1; if (in_array(1, $ndatas[$b])) { $ndatas[$c] = $value; $c ++; } } } return $this->verData = $ndatas; } /** * Display phone number... * * @return unknown */ public function showPhone ($ndatas) { $phone = null; $d = 0; foreach ($ndatas as $key => $val) { if (in_array(1, $val)) { foreach ($val as $k => $v) { $ndArr[$d] .= $v; } } if (! in_array(1, $val)) { $d ++; } } foreach ($ndArr as $key01 => $val01) { $phone .= $this->initData($val01); } return $phone; } /** * Display separately... * * @param unknown_type $dataArr */ function drawWH ($dataArr) { if (is_array($dataArr)) { foreach ($dataArr as $key => $val) { foreach ($val as $k => $v) { if ($v == 0) { $c .= "<font color='#FFFFFF'>" . $v . "<"/font>"; } else { $c .= $v; } } $c .= "<br"/>"; } } echo $c; } /** * Initial data... * * @param unknown_type $numStr * @return unknown */ public function initData ($numStr) { $result = null; $data = array( 0 => '000011111000001111111110011000000011110000000001110000000001110000000001110000000001011000000011011100000111000111111100000001110000', 1 => '011000000000011000000000111111111111111111111111', 2 => '001000000011011000000111110000001101110000011001110000011001110000110001111001100001011111100001000110000001', 3 => '001000000010011000000011110000000001110000000001110000110001110000110001011001110011011111011111000110001100', 4 => '000000001100000000111100000001111100000011101100000111001100001100001100011000001100111111111111111111111111000000001100000000000100', 5 => '111111000001111111000001110001000001110001000001110001100001110001100001110000110011110000111111000000001100', 6 => '000011111000001111111110011000110011110001100001110001100001110001100001110001100001010001110011010000111111000000001100', 7 => '110000000000110000000111110000111111110001110000110111000000111100000000111000000000111000000000', 8 => '000100011110011111111111110011100001110001100001110001100001110001100001110011100001011111111111000100011110', 9 => '001111000000011111100001110000110001110000110001110000110001110000110001011000100001011111100111000111111110000001110000' ); foreach ($data as $key => $val) { similar_text($numStr, $val, $pre);}} if ($pre > 95) { // Similarity95% above $result = $key; break; } } return $result; } } $imgPath = "http://bj.ganji.com/tel/5463013757650d6c5e31093e563c51315b6c5c6c5237.png"; $gjPhone = new gjPhone($imgPath); // Perform Color Separation $gjPhone->getHec(); // Draw Horizontal Data $horData = $gjPhone->magHorData(); >echo "===============Horizontal Data==============<br/><br/><br/>"; $gjPhone->drawWH($horData); // Draw Vertical Data $verData = $gjPhone->magVerData($horData); echo "<br/><br/><br/>===============Vertical Data==============< br/><br/><br/>"; $gjPhone->drawWH($verData); // Output Phone $phone = $gjPhone->showPhone($verData); echo "<br/><br/><br/>===============Phone==============<br /><br/><br/>" . $phone;
That's all for this article, I hope it will be helpful to everyone's learning, and I also hope everyone will support the Shouting Tutorial more.
Statement: The content of this article is from the network, the copyright belongs to the original author, the content is contributed and uploaded by Internet users spontaneously, this website does not own the copyright, has not been manually edited, and does not assume relevant legal liabilities. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report abuse, and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.)