2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,4 +1,4 @@
|
|||
my regex bitcoin-address {
|
||||
my $bitcoin-address = rx/
|
||||
<+alnum-[0IOl]> ** 26..* # an address is at least 26 characters long
|
||||
<?{
|
||||
use Digest::SHA;
|
||||
|
|
@ -12,6 +12,6 @@ my regex bitcoin-address {
|
|||
.polymod(256 xx 24)
|
||||
.reverse;
|
||||
}>
|
||||
}
|
||||
/;
|
||||
|
||||
say "Here is a bitcoin address: 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" ~~ /<bitcoin-address>/;
|
||||
say "Here is a bitcoin address: 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" ~~ $bitcoin-address;
|
||||
|
|
|
|||
|
|
@ -1,43 +1,30 @@
|
|||
(load "sha256.l")
|
||||
|
||||
(setq *Alphabet
|
||||
(chop "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"))
|
||||
|
||||
# if returns NIL then adress is already invalid
|
||||
(de base58 (Str)
|
||||
(let N 0
|
||||
(for L (chop Str)
|
||||
(setq N
|
||||
(+
|
||||
(* N 58)
|
||||
(index L *Alphabet)
|
||||
-1 ) ) )
|
||||
|
||||
N )
|
||||
)
|
||||
|
||||
(de sha256 (Lst)
|
||||
(native "libcrypto.so" "SHA256"
|
||||
'(B . 32)
|
||||
(cons
|
||||
NIL
|
||||
(32)
|
||||
(native "libcrypto.so" "SHA256" '(B . 32)
|
||||
(cons NIL (32) Lst) (length Lst) '(NIL (32))) )
|
||||
32
|
||||
'(NIL (32)) ) )
|
||||
|
||||
(de bytes25 (N)
|
||||
(flip
|
||||
(make
|
||||
(do 25
|
||||
(link (% N 256))
|
||||
(setq N (/ N 256)) ) ) ) )
|
||||
|
||||
(chop "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") )
|
||||
(de unbase58 (Str)
|
||||
(let (Str (chop Str) Lst (need 25 0) C)
|
||||
(while (setq C (dec (index (pop 'Str) *Alphabet)))
|
||||
(for (L Lst L)
|
||||
(set
|
||||
L (& (inc 'C (* 58 (car L))) 255)
|
||||
'C (/ C 256) )
|
||||
(pop 'L) ) )
|
||||
(flip Lst) ) )
|
||||
(de valid (Str)
|
||||
(and
|
||||
(base58 Str)
|
||||
(bytes25 @)
|
||||
(setq @@ (unbase58 Str))
|
||||
(=
|
||||
(head 4 (sha256 (head 21 @)))
|
||||
(tail 4 @) ) ) )
|
||||
|
||||
(bye)
|
||||
(head 4 (sha256 (sha256 (head 21 @@))))
|
||||
(tail 4 @@) ) ) )
|
||||
(test
|
||||
T
|
||||
(valid "17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j") )
|
||||
(test
|
||||
T
|
||||
(=
|
||||
NIL
|
||||
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j")
|
||||
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!")
|
||||
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz")
|
||||
(valid "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz") ) )
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
; using PureBasic 5.50 (x64)
|
||||
EnableExplicit
|
||||
|
||||
Macro IsValid(expression)
|
||||
If expression
|
||||
PrintN("Valid")
|
||||
Else
|
||||
PrintN("Invalid")
|
||||
EndIf
|
||||
EndMacro
|
||||
|
||||
Procedure.i DecodeBase58(Address$, Array result.a(1))
|
||||
Protected i, j, p
|
||||
Protected charSet$ = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
Protected c$
|
||||
|
||||
For i = 1 To Len(Address$)
|
||||
c$ = Mid(Address$, i, 1)
|
||||
p = FindString(charSet$, c$) - 1
|
||||
If p = -1 : ProcedureReturn #False : EndIf; Address contains invalid Base58 character
|
||||
For j = 24 To 1 Step -1
|
||||
p + 58 * result(j)
|
||||
result(j) = p % 256
|
||||
p / 256
|
||||
Next j
|
||||
If p <> 0 : ProcedureReturn #False : EndIf ; Address is too long
|
||||
Next i
|
||||
ProcedureReturn #True
|
||||
EndProcedure
|
||||
|
||||
Procedure HexToBytes(hex$, Array result.a(1))
|
||||
Protected i
|
||||
For i = 1 To Len(hex$) - 1 Step 2
|
||||
result(i/2) = Val("$" + Mid(hex$, i, 2))
|
||||
Next
|
||||
EndProcedure
|
||||
|
||||
Procedure.i IsBitcoinAddressValid(Address$)
|
||||
Protected format$, digest$
|
||||
Protected i, isValid
|
||||
Protected Dim result.a(24)
|
||||
Protected Dim result2.a(31)
|
||||
Protected result$, result2$
|
||||
; Address length must be between 26 and 35 - see 'https://en.bitcoin.it/wiki/Address'
|
||||
If Len(Address$) < 26 Or Len(Address$) > 35 : ProcedureReturn #False : EndIf
|
||||
; and begin with either 1 or 3 which is the format number
|
||||
format$ = Left(Address$, 1)
|
||||
If format$ <> "1" And format$ <> "3" : ProcedureReturn #False : EndIf
|
||||
isValid = DecodeBase58(Address$, result())
|
||||
If Not isValid : ProcedureReturn #False : EndIf
|
||||
UseSHA2Fingerprint(); Using functions from PB's built-in Cipher library
|
||||
digest$ = Fingerprint(@result(), 21, #PB_Cipher_SHA2, 256); apply SHA2-256 to first 21 bytes
|
||||
HexToBytes(digest$, result2()); change hex string to ascii array
|
||||
digest$ = Fingerprint(@result2(), 32, #PB_Cipher_SHA2, 256); apply SHA2-256 again to all 32 bytes
|
||||
HexToBytes(digest$, result2())
|
||||
result$ = PeekS(@result() + 21, 4, #PB_Ascii); last 4 bytes
|
||||
result2$ = PeekS(@result2(), 4, #PB_Ascii); first 4 bytes
|
||||
If result$ <> result2$ : ProcedureReturn #False : EndIf
|
||||
ProcedureReturn #True
|
||||
EndProcedure
|
||||
|
||||
If OpenConsole()
|
||||
Define address$ = "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"
|
||||
Define address2$ = "1BGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"
|
||||
Define address3$ = "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I"
|
||||
Print(address$ + " -> ")
|
||||
IsValid(IsBitcoinAddressValid(address$))
|
||||
Print(address2$ + " -> ")
|
||||
IsValid(IsBitcoinAddressValid(address2$))
|
||||
Print(address3$ + " -> ")
|
||||
IsValid(IsBitcoinAddressValid(address3$))
|
||||
PrintN("")
|
||||
PrintN("Press any key to close the console")
|
||||
Repeat: Delay(10) : Until Inkey() <> ""
|
||||
CloseConsole()
|
||||
EndIf
|
||||
Loading…
Add table
Add a link
Reference in a new issue