Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.59% covered (success)
98.59%
70 / 71
85.71% covered (success)
85.71%
6 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Vizhash16x16
98.59% covered (success)
98.59%
70 / 71
85.71% covered (success)
85.71%
6 / 7
20
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 generate
96.67% covered (success)
96.67%
29 / 30
0.00% covered (danger)
0.00%
0 / 1
5
 getInt
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getX
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getY
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 degrade
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
4
 drawshape
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
7
1<?php
2/**
3 * VizHash_GD
4 *
5 * Visual Hash implementation in php4+GD,
6 * stripped down and modified version for PrivateBin
7 *
8 * @link      https://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd
9 * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
10 * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
11 * @version   0.0.5 beta PrivateBin 1.7.2
12 */
13
14namespace PrivateBin;
15
16/**
17 * Vizhash16x16
18 *
19 * Example:
20 * $vz = new Vizhash16x16();
21 * $data = $vz->generate(sha512('hello'));
22 * header('Content-type: image/png');
23 * echo $data;
24 * exit;
25 */
26class Vizhash16x16
27{
28    /**
29     * hash values
30     *
31     * @access private
32     * @var    array
33     */
34    private $VALUES;
35
36    /**
37     * index of current value
38     *
39     * @access private
40     * @var    int
41     */
42    private $VALUES_INDEX;
43
44    /**
45     * image width
46     *
47     * @access private
48     * @var    int
49     */
50    private $width;
51
52    /**
53     * image height
54     *
55     * @access private
56     * @var    int
57     */
58    private $height;
59
60    /**
61     * constructor
62     *
63     * @access public
64     */
65    public function __construct()
66    {
67        $this->width  = 16;
68        $this->height = 16;
69    }
70
71    /**
72     * Generate a 16x16 png corresponding to $text.
73     *
74     * The given text should to be 128 to 150 characters long
75     *
76     * @access public
77     * @param  string $text
78     * @return string PNG data. Or empty string if GD is not available.
79     */
80    public function generate($text)
81    {
82        if (!function_exists('gd_info')) {
83            return '';
84        }
85
86        $textlen = strlen($text);
87
88        // We convert the hash into an array of integers.
89        $this->VALUES = array();
90        for ($i = 0; $i < $textlen; $i = $i + 2) {
91            array_push($this->VALUES, hexdec(substr($text, $i, 2)));
92        }
93        $this->VALUES_INDEX = 0; // to walk the array.
94
95        // Then use these integers to drive the creation of an image.
96        $image = imagecreatetruecolor($this->width, $this->height);
97
98        $r = $r0 = $this->getInt();
99        $g = $g0 = $this->getInt();
100        $b = $b0 = $this->getInt();
101
102        // First, create an image with a specific gradient background.
103        $op = 'v';
104        if (($this->getInt() % 2) == 0) {
105            $op = 'h';
106        }
107        $image = $this->degrade($image, $op, array($r0, $g0, $b0), array(0, 0, 0));
108
109        for ($i = 0; $i < 7; ++$i) {
110            $action = $this->getInt();
111            $color  = imagecolorallocate($image, $r, $g, $b);
112            $r      = $r0      = (int) ($r0 + $this->getInt() / 25) % 256;
113            $g      = $g0      = (int) ($g0 + $this->getInt() / 25) % 256;
114            $b      = $b0      = (int) ($b0 + $this->getInt() / 25) % 256;
115            $this->drawshape($image, $action, $color);
116        }
117
118        $color = imagecolorallocate($image, $this->getInt(), $this->getInt(), $this->getInt());
119        $this->drawshape($image, $this->getInt(), $color);
120        ob_start();
121        imagepng($image);
122        $imagedata = ob_get_contents();
123        ob_end_clean();
124        imagedestroy($image);
125
126        return $imagedata;
127    }
128
129    /**
130     * Returns a single integer from the $VALUES array (0...255)
131     *
132     * @access private
133     * @return int
134     */
135    private function getInt()
136    {
137        $v = $this->VALUES[$this->VALUES_INDEX];
138        ++$this->VALUES_INDEX;
139        $this->VALUES_INDEX %= count($this->VALUES); // Wrap around the array
140        return $v;
141    }
142
143    /**
144     * Returns a single integer from the array (roughly mapped to image width)
145     *
146     * @access private
147     * @return int
148     */
149    private function getX()
150    {
151        return (int) ($this->width * $this->getInt() / 256);
152    }
153
154    /**
155     * Returns a single integer from the array (roughly mapped to image height)
156     *
157     * @access private
158     * @return int
159     */
160    private function getY()
161    {
162        return (int) ($this->height * $this->getInt() / 256);
163    }
164
165    /**
166     * Gradient function
167     *
168     * taken from:
169     * @link   https://www.supportduweb.com/scripts_tutoriaux-code-source-41-gd-faire-un-degrade-en-php-gd-fonction-degrade-imagerie.html
170     *
171     * @access private
172     * @param  resource $img
173     * @param  string $direction
174     * @param  array $color1
175     * @param  array $color2
176     * @return resource
177     */
178    private function degrade($img, $direction, $color1, $color2)
179    {
180        if ($direction == 'h') {
181            $size    = imagesx($img);
182            $sizeinv = imagesy($img);
183        } else {
184            $size    = imagesy($img);
185            $sizeinv = imagesx($img);
186        }
187        $diffs = array(
188            ($color2[0] - $color1[0]) / $size,
189            ($color2[1] - $color1[1]) / $size,
190            ($color2[2] - $color1[2]) / $size,
191        );
192        for ($i = 0; $i < $size; ++$i) {
193            $r = $color1[0] + ((int) $diffs[0] * $i);
194            $g = $color1[1] + ((int) $diffs[1] * $i);
195            $b = $color1[2] + ((int) $diffs[2] * $i);
196            if ($direction == 'h') {
197                imageline($img, $i, 0, $i, $sizeinv, imagecolorallocate($img, $r, $g, $b));
198            } else {
199                imageline($img, 0, $i, $sizeinv, $i, imagecolorallocate($img, $r, $g, $b));
200            }
201        }
202        return $img;
203    }
204
205    /**
206     * Draw a shape
207     *
208     * @access private
209     * @param  resource $image
210     * @param  int $action
211     * @param  int $color
212     */
213    private function drawshape($image, $action, $color)
214    {
215        switch ($action % 7) {
216            case 0:
217                imagefilledrectangle($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color);
218                break;
219            case 1:
220            case 2:
221                imagefilledellipse($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color);
222                break;
223            case 3:
224                $points = array($this->getX(), $this->getY(), $this->getX(), $this->getY(), $this->getX(), $this->getY(), $this->getX(), $this->getY());
225                version_compare(PHP_VERSION, '8.1', '<') ? imagefilledpolygon($image, $points, 4, $color) : imagefilledpolygon($image, $points, $color);
226                break;
227            default:
228                $start = (int) ($this->getInt() * 360 / 256);
229                $end   = (int) ($start + $this->getInt() * 180 / 256);
230                imagefilledarc($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $start, $end, $color, IMG_ARC_PIE);
231        }
232    }
233}