Add bitcoin address validator from https://bitcointalk.org/index.php?topic=16763.0
[elbandi:minifaucet.git] / validator.php
1 <?php
2 //hex input must be in uppercase, with no leading 0x
3
4 define("ADDRESSVERSION","00"); //this is a hex byte
5
6 function decodeHex($hex)
7 {
8         $hex=strtoupper($hex);
9         $chars="0123456789ABCDEF";
10         $return="0";
11         for($i=0;$i<strlen($hex);$i++)
12         {
13                 $current=(string)strpos($chars,$hex[$i]);
14                 $return=(string)bcmul($return,"16",0);
15                 $return=(string)bcadd($return,$current,0);
16         }
17         return $return;
18 }
19
20 function encodeHex($dec)
21 {
22         $chars="0123456789ABCDEF";
23         $return="";
24         while (bccomp($dec,0)==1)
25         {
26                 $dv=(string)bcdiv($dec,"16",0);
27                 $rem=(integer)bcmod($dec,"16");
28                 $dec=$dv;
29                 $return=$return.$chars[$rem];
30         }
31         return strrev($return);
32 }
33
34 function decodeBase58($base58)
35 {
36         $origbase58=$base58;
37         
38         $chars="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
39         $return="0";
40         for($i=0;$i<strlen($base58);$i++)
41         {
42                 $current=(string)strpos($chars,$base58[$i]);
43                 $return=(string)bcmul($return,"58",0);
44                 $return=(string)bcadd($return,$current,0);
45         }
46         
47         $return=encodeHex($return);
48         
49         //leading zeros
50         for($i=0;$i<strlen($origbase58)&&$origbase58[$i]=="1";$i++)
51         {
52                 $return="00".$return;
53         }
54         
55         if(strlen($return)%2!=0)
56         {
57                 $return="0".$return;
58         }
59         
60         return $return;
61 }
62
63 function encodeBase58($hex)
64 {
65         if(strlen($hex)%2!=0)
66         {
67                 die("encodeBase58: uneven number of hex characters");
68         }
69         $orighex=$hex;
70         
71         $chars="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
72         $hex=decodeHex($hex);
73         $return="";
74         while (bccomp($hex,0)==1)
75         {
76                 $dv=(string)bcdiv($hex,"58",0);
77                 $rem=(integer)bcmod($hex,"58");
78                 $hex=$dv;
79                 $return=$return.$chars[$rem];
80         }
81         $return=strrev($return);
82         
83         //leading zeros
84         for($i=0;$i<strlen($orighex)&&substr($orighex,$i,2)=="00";$i+=2)
85         {
86                 $return="1".$return;
87         }
88         
89         return $return;
90 }
91
92 function hash160ToAddress($hash160,$addressversion=ADDRESSVERSION)
93 {
94         $hash160=$addressversion.$hash160;
95         $check=pack("H*" , $hash160);
96         $check=hash("sha256",hash("sha256",$check,true));
97         $check=substr($check,0,8);
98         $hash160=strtoupper($hash160.$check);
99         return encodeBase58($hash160);
100 }
101
102 function addressToHash160($addr)
103 {
104         $addr=decodeBase58($addr);
105         $addr=substr($addr,2,strlen($addr)-10);
106         return $addr;
107 }
108
109 function checkAddress($addr,$addressversion=ADDRESSVERSION)
110 {
111         $addr=decodeBase58($addr);
112         if(strlen($addr)!=50)
113         {
114                 return false;
115         }
116         $version=substr($addr,0,2);
117         if(hexdec($version)>hexdec($addressversion))
118         {
119                 return false;
120         }
121         $check=substr($addr,0,strlen($addr)-8);
122         $check=pack("H*" , $check);
123         $check=strtoupper(hash("sha256",hash("sha256",$check,true)));
124         $check=substr($check,0,8);
125         return $check==substr($addr,strlen($addr)-8);
126 }
127
128 function hash160($data)
129 {
130         $data=pack("H*" , $data);
131         return strtoupper(hash("ripemd160",hash("sha256",$data,true)));
132 }
133
134 function pubKeyToAddress($pubkey)
135 {
136         return hash160ToAddress(hash160($pubkey));
137 }
138
139 function remove0x($string)
140 {
141         if(substr($string,0,2)=="0x"||substr($string,0,2)=="0X")
142         {
143                 $string=substr($string,2);
144         }
145         return $string;
146 }