Completed
Push — master ( 6b32ff...8661ae )
by thomas
27:14 queued 36s
created

Math   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 78.95%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 25
c 1
b 0
f 0
lcom 1
cbo 3
dl 0
loc 177
ccs 45
cts 57
cp 0.7895
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A greaterThan() 0 4 1
A greatherThanEq() 0 4 1
A lessThan() 0 4 1
A lessThanEq() 0 4 1
A notEq() 0 4 1
A eq() 0 4 1
A getBinaryMath() 0 4 1
A isEven() 0 4 1
A bitwiseOr() 0 4 1
A divQr() 0 8 1
C writeCompact() 0 22 8
A getLow64() 0 5 1
B parseCompact() 0 26 6
1
<?php
2
3
namespace BitWasp\Bitcoin\Math;
4
5
use \Mdanter\Ecc\Math\Gmp;
6
use Mdanter\Ecc\Util\NumberSize;
7
8
class Math extends Gmp
9
{
10
    /**
11
     * @param int|string $first
12
     * @param int|string $second
13
     * @return bool
14
     */
15
    public function notEq($first, $second)
16
    {
17
        return $this->cmp($first, $second) !== 0;
18
    }
19
20
    /**
21
     * @param $first
22
     * @param $second
23
     * @return bool
24
     */
25
    public function eq($first, $second)
26
    {
27
        return $this->cmp($first, $second) === 0;
28
    }
29
30
    /**
31
     * @param int|string $first
32
     * @param int|string $second
33
     * @return bool
34
     */
35
    public function greaterThan($first, $second)
36
    {
37
        return $this->cmp($first, $second) > 0;
38
    }
39
40
    /**
41
     * @param int|string $first
42
     * @param int|string $second
43
     * @return bool
44
     */
45
    public function greatherThanEq($first, $second)
46
    {
47
        return $this->cmp($first, $second) >= 0;
48
    }
49
50
    /**
51
     * @param int|string $first
52
     * @param int|string $second
53
     * @return bool
54
     */
55
    public function lessThan($first, $second)
56
    {
57
        return $this->cmp($first, $second) > 0;
58
    }
59
60
    /**
61
     * @param int|string $first
62
     * @param int|string $second
63
     * @return bool
64
     */
65
    public function lessThanEq($first, $second)
66
    {
67
        return $this->cmp($first, $second) >= 0;
68
    }
69
70
    /**
71
     * @return BinaryMath
72
     */
73 132
    public function getBinaryMath()
74
    {
75 132
        return new BinaryMath($this);
76
    }
77
78
    /**
79
     * @param $integer
80
     * @return bool
81
     */
82 222
    public function isEven($integer)
83
    {
84 222
        return $this->cmp($this->mod($integer, 2), 0) === 0;
85
    }
86
87
    /**
88
     * @param int|string $int
89
     * @param int|string $otherInt
90
     * @return string
91
     */
92 864
    public function bitwiseOr($int, $otherInt)
93
    {
94 864
        return gmp_strval(gmp_or(gmp_init($int, 10), gmp_init($otherInt, 10)), 10);
95
    }
96
97
    /**
98
     * Similar to gmp_div_qr, return a tuple containing the
99
     * result and the remainder
100
     *
101
     * @param $dividend
102
     * @param integer $divisor
103
     * @return array
104
     */
105 222
    public function divQr($dividend, $divisor)
106
    {
107
        // $div = n / q
108 222
        $div = $this->div($dividend, $divisor);
109
        // $remainder = n - (n / q) * q
110 222
        $remainder = $this->sub($dividend, $this->mul($div, $divisor));
111 222
        return array($div, $remainder);
112
    }
113
114
    /**
115
     * @param int|string $compact
116
     * @param bool|false $isNegative
117
     * @param bool|false $isOverflow
118
     * @return int|string
119
     */
120 1260
    public function writeCompact($compact, &$isNegative, &$isOverflow)
121
    {
122
123 1260
        $size = $this->rightShift($compact, 24);
124 1260
        $word = $this->bitwiseAnd($compact, $this->hexDec('007fffff'));
125 1260
        if ($this->cmp($size, 3) <= 0) {
126 78
            $word = $this->rightShift($word, $this->mul(8, $this->sub(3, $size)));
127 78
        } else {
128 1182
            $word = $this->leftShift($word, $this->mul(8, $this->sub($size, 3)));
129
        }
130
131
        // isNegative: $word != 0 && $uint32 & 0x00800000 != 0
132
        // isOverflow: $word != 0 && (($size > 34) || ($word > 0xff && $size > 33) || ($word > 0xffff && $size  >32))
133 1260
        $isNegative = (($this->cmp($word, 0) !== 0) && ($this->cmp($this->bitwiseAnd($compact, $this->hexDec('0x00800000')), 0) === 1));
134 1260
        $isOverflow = $this->cmp($word, 0) !== 0 && (
135 1194
                ($this->cmp($size, 34) > 0)
136 1188
                || ($this->cmp($word, 0xff) > 0 && $this->cmp($size, 33) > 0)
137 1188
                || ($this->cmp($word, 0xffff) > 0 && $this->cmp($size, 32) > 0)
138 1260
            );
139
140 1260
        return $word;
141
    }
142
143
    /**
144
     * @param int|string $integer
145
     * @return int|string
146
     */
147 108
    public function getLow64($integer)
148
    {
149 108
        $bits = str_pad($this->baseConvert($integer, 10, 2), 64, '0', STR_PAD_LEFT);
150 108
        return $this->baseConvert(substr($bits, 0, 64), 2, 10);
151
    }
152
153
    /**
154
     * @param int|string $integer
155
     * @param bool $fNegative
156
     * @return int|string
157
     */
158 114
    public function parseCompact($integer, $fNegative)
159
    {
160 114
        if (!is_bool($fNegative)) {
161 6
            throw new \InvalidArgumentException('CompactInteger::read() - flag must be boolean!');
162
        }
163
164 108
        $size = (int) NumberSize::bnNumBytes($this, $integer);
165 108
        if ($this->cmp($size, 3) <= 0) {
166 84
            $compact = $this->leftShift($this->getLow64($integer), $this->mul(8, $this->sub(3, $size)));
167 84
        } else {
168 24
            $compact = $this->rightShift($integer, $this->mul(8, $this->sub($size, 3)));
169 24
            $compact = $this->getLow64($compact);
170
        }
171
172 108
        if ($this->cmp($this->bitwiseAnd($compact, $this->hexDec('00800000')), 0) > 0) {
173 6
            $compact = $this->rightShift($compact, 8);
174 6
            $size++;
175 6
        }
176
177 108
        $compact = $this->bitwiseOr($compact, $this->leftShift($size, 24));
178 108
        if ($fNegative && $this->cmp($this->bitwiseAnd($compact, $this->hexDec('007fffff')), 0) > 0) { /// ?
179 12
            $compact = $this->bitwiseOr($compact, $this->hexDec('00800000'));
180 12
        }
181
182 108
        return $compact;
183
    }
184
}
185