// File: jeffchan[P]blockchain-parser/Base58.cpp
// Function: CBDecodeBase58(BigNumber*, char const*)
bool CBDecodeBase58(BigNumber * bi,const char * str)
{
	// ??? Quite likely these functions can be improved
	BigNumber bi2(NULL,1);

	uint32_t slen = (uint32_t)strlen(str);

	for (uint32_t x = slen - 1;; x--)
	{ // Working backwards
		// Get index in alphabet array
		uint8_t alphaIndex = str[x];
		if (alphaIndex != 49)
		{ // If not 1
			if (str[x] < 58)
			{ // Numbers
				alphaIndex -= 49;
			}
			else if (str[x] < 73)
			{ // A-H
				alphaIndex -= 56;
			}
			else if (str[x] < 79)
			{ // J-N
				alphaIndex -= 57;
			}
			else if (str[x] < 91)
			{ // P-Z
				alphaIndex -= 58;
			}
			else if (str[x] < 108)
			{ // a-k
				alphaIndex -= 64;
			}
			else
			{ // m-z
				alphaIndex -= 65;
			}
			if (! BigNumberFromPowUInt8(&bi2, 58, (uint8_t)(slen - 1 - x)))
			{
				// Error occured.
				return false;
			}
			if (! BigNumberEqualsMultiplicationByUInt8(&bi2, alphaIndex))
			{
				// Error occured.
				return false;
			}
			if (! BigNumberEqualsAdditionByBigInt(bi, &bi2))
			{
				// Error occured.
				return false;
			}
		}
		if (!x)
			break;
	}
	// Got BigNumber from base-58 string. Add zeros on end.
	uint8_t zeros = 0;
	for (uint8_t x = 0; x < slen; x++)
	{
		if (str[x] == '1')
		{
			zeros++;
		}
		else
		{
			break;
		}
	}
	if (zeros) 
	{
		bi->length += zeros;
		assert( bi->length < MAX_BIG_NUMBER );
		memset(bi->data + bi->length - zeros, 0, zeros);
	}
	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
leaq -0x11c(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x1, %edx
callq 0x31e0
movq -0x18(%rbp), %rdi
callq 0x2090
movl %eax, -0x120(%rbp)
movl -0x120(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x124(%rbp)
movq -0x18(%rbp), %rax
movl -0x124(%rbp), %ecx
movb (%rax,%rcx), %al
movb %al, -0x125(%rbp)
movzbl -0x125(%rbp), %eax
cmpl $0x31, %eax
je 0x2ccf
movq -0x18(%rbp), %rax
movl -0x124(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x3a, %eax
jge 0x2bb1
movzbl -0x125(%rbp), %eax
subl $0x31, %eax
movb %al, -0x125(%rbp)
jmp 0x2c60
movq -0x18(%rbp), %rax
movl -0x124(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x49, %eax
jge 0x2bd9
movzbl -0x125(%rbp), %eax
subl $0x38, %eax
movb %al, -0x125(%rbp)
jmp 0x2c5e
movq -0x18(%rbp), %rax
movl -0x124(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x4f, %eax
jge 0x2bfe
movzbl -0x125(%rbp), %eax
subl $0x39, %eax
movb %al, -0x125(%rbp)
jmp 0x2c5c
movq -0x18(%rbp), %rax
movl -0x124(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x5b, %eax
jge 0x2c23
movzbl -0x125(%rbp), %eax
subl $0x3a, %eax
movb %al, -0x125(%rbp)
jmp 0x2c5a
movq -0x18(%rbp), %rax
movl -0x124(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x6c, %eax
jge 0x2c48
movzbl -0x125(%rbp), %eax
subl $0x40, %eax
movb %al, -0x125(%rbp)
jmp 0x2c58
movzbl -0x125(%rbp), %eax
subl $0x41, %eax
movb %al, -0x125(%rbp)
jmp 0x2c5a
jmp 0x2c5c
jmp 0x2c5e
jmp 0x2c60
movl -0x120(%rbp), %eax
subl $0x1, %eax
subl -0x124(%rbp), %eax
leaq -0x11c(%rbp), %rdi
movl $0x3a, %esi
movzbl %al, %edx
callq 0x2a20
testb $0x1, %al
jne 0x2c90
movb $0x0, -0x1(%rbp)
jmp 0x2dcd
leaq -0x11c(%rbp), %rdi
movzbl -0x125(%rbp), %esi
callq 0x2760
testb $0x1, %al
jne 0x2cb0
movb $0x0, -0x1(%rbp)
jmp 0x2dcd
movq -0x10(%rbp), %rdi
leaq -0x11c(%rbp), %rsi
callq 0x24c0
testb $0x1, %al
jne 0x2ccd
movb $0x0, -0x1(%rbp)
jmp 0x2dcd
jmp 0x2ccf
cmpl $0x0, -0x124(%rbp)
jne 0x2cda
jmp 0x2cf0
jmp 0x2cdc
movl -0x124(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x124(%rbp)
jmp 0x2b66
movb $0x0, -0x126(%rbp)
movb $0x0, -0x127(%rbp)
movzbl -0x127(%rbp), %eax
cmpl -0x120(%rbp), %eax
jae 0x2d45
movq -0x18(%rbp), %rax
movzbl -0x127(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x31, %eax
jne 0x2d31
movb -0x126(%rbp), %al
addb $0x1, %al
movb %al, -0x126(%rbp)
jmp 0x2d33
jmp 0x2d45
jmp 0x2d35
movb -0x127(%rbp), %al
addb $0x1, %al
movb %al, -0x127(%rbp)
jmp 0x2cfe
cmpb $0x0, -0x126(%rbp)
je 0x2dc9
movzbl -0x126(%rbp), %ecx
movq -0x10(%rbp), %rax
addl 0x100(%rax), %ecx
movl %ecx, 0x100(%rax)
movq -0x10(%rbp), %rax
cmpl $0x100, 0x100(%rax)     # imm = 0x100
jae 0x2d77
jmp 0x2d96
leaq 0x2d32b(%rip), %rdi     # 0x300a9
leaq 0x2d29a(%rip), %rsi     # 0x3001f
movl $0x176, %edx            # imm = 0x176
leaq 0x2d334(%rip), %rcx     # 0x300c5
callq 0x20c0
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x100(%rax), %eax
addq %rax, %rdi
movzbl -0x126(%rbp), %eax
movslq %eax, %rcx
xorl %eax, %eax
subq %rcx, %rax
addq %rax, %rdi
movzbl -0x126(%rbp), %eax
movl %eax, %edx
xorl %esi, %esi
callq 0x20b0
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
nopl (%rax,%rax)