// File: tenup-coin[P]seeder/util.cpp
// Function: DecodeBase32(char const*, bool*)
vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
{
    static const int decode32_table[256] =
    {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
        -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1,  0,  1,  2,
         3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
        23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    };

    if (pfInvalid)
        *pfInvalid = false;

    vector<unsigned char> vchRet;
    vchRet.reserve((strlen(p))*5/8);

    int mode = 0;
    int left = 0;

    while (1)
    {
         int dec = decode32_table[(unsigned char)*p];
         if (dec == -1) break;
         p++;
         switch (mode)
         {
             case 0: // we have no bits and get 5
                 left = dec;
                 mode = 1;
                 break;

              case 1: // we have 5 bits and keep 2
                  vchRet.push_back((left<<3) | (dec>>2));
                  left = dec & 3;
                  mode = 2;
                  break;

             case 2: // we have 2 bits and keep 7
                 left = left << 5 | dec;
                 mode = 3;
                 break;

             case 3: // we have 7 bits and keep 4
                 vchRet.push_back((left<<1) | (dec>>4));
                 left = dec & 15;
                 mode = 4;
                 break;

             case 4: // we have 4 bits, and keep 1
                 vchRet.push_back((left<<4) | (dec>>1));
                 left = dec & 1;
                 mode = 5;
                 break;

             case 5: // we have 1 bit, and keep 6
                 left = left << 5 | dec;
                 mode = 6;
                 break;

             case 6: // we have 6 bits, and keep 3
                 vchRet.push_back((left<<2) | (dec>>3));
                 left = dec & 7;
                 mode = 7;
                 break;

             case 7: // we have 3 bits, and keep 0
                 vchRet.push_back((left<<5) | dec);
                 mode = 0;
                 break;
         }
    }

    if (pfInvalid)
        switch (mode)
        {
            case 0: // 8n base32 characters processed: ok
                break;

            case 1: // 8n+1 base32 characters processed: impossible
            case 3: //   +3
            case 6: //   +6
                *pfInvalid = true;
                break;

            case 2: // 8n+2 base32 characters processed: require '======'
                if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
                    *pfInvalid = true;
                break;

            case 4: // 8n+4 base32 characters processed: require '===='
                if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
                    *pfInvalid = true;
                break;

            case 5: // 8n+5 base32 characters processed: require '==='
                if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
                    *pfInvalid = true;
                break;

            case 7: // 8n+7 base32 characters processed: require '='
                if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
                    *pfInvalid = true;
                break;
        }

    return vchRet;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x50(%rbp)
movq %rdi, %rax
movq %rax, -0x48(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x318fd
movq -0x18(%rbp), %rax
movb $0x0, (%rax)
movq -0x50(%rbp), %rdi
movb $0x0, -0x19(%rbp)
callq 0x15600
movq -0x10(%rbp), %rdi
callq 0x4210
movq -0x50(%rbp), %rdi
leaq (%rax,%rax,4), %rsi
shrq $0x3, %rsi
callq 0x31e10
jmp 0x31926
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
jmp 0x31936
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
movl %eax, %ecx
leaq 0x2a6a(%rip), %rax      # 0x343b0
movl (%rax,%rcx,4), %eax
movl %eax, -0x38(%rbp)
cmpl $-0x1, -0x38(%rbp)
jne 0x31971
jmp 0x31ad5
movq -0x50(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
callq 0x15550
jmp 0x31c82
movq -0x10(%rbp), %rax
incq %rax
movq %rax, -0x10(%rbp)
movl -0x30(%rbp), %eax
movq %rax, -0x58(%rbp)
subq $0x7, %rax
ja 0x31ad0
movq -0x58(%rbp), %rax
leaq 0x29ac(%rip), %rcx      # 0x34344
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl -0x38(%rbp), %eax
movl %eax, -0x34(%rbp)
movl $0x1, -0x30(%rbp)
jmp 0x31ad0
movq -0x50(%rbp), %rdi
movl -0x34(%rbp), %eax
shll $0x3, %eax
movl -0x38(%rbp), %ecx
shrl $0x2, %ecx
orl %ecx, %eax
movb %al, -0x39(%rbp)
leaq -0x39(%rbp), %rsi
callq 0x15620
jmp 0x319d3
movl -0x38(%rbp), %eax
andl $0x3, %eax
movl %eax, -0x34(%rbp)
movl $0x2, -0x30(%rbp)
jmp 0x31ad0
movl -0x34(%rbp), %eax
shll $0x5, %eax
orl -0x38(%rbp), %eax
movl %eax, -0x34(%rbp)
movl $0x3, -0x30(%rbp)
jmp 0x31ad0
movq -0x50(%rbp), %rdi
movl -0x34(%rbp), %eax
addl %eax, %eax
movl -0x38(%rbp), %ecx
shrl $0x4, %ecx
orl %ecx, %eax
movb %al, -0x3a(%rbp)
leaq -0x3a(%rbp), %rsi
callq 0x15620
jmp 0x31a1f
movl -0x38(%rbp), %eax
andl $0xf, %eax
movl %eax, -0x34(%rbp)
movl $0x4, -0x30(%rbp)
jmp 0x31ad0
movq -0x50(%rbp), %rdi
movl -0x34(%rbp), %eax
shll $0x4, %eax
movl -0x38(%rbp), %ecx
shrl %ecx
orl %ecx, %eax
movb %al, -0x3b(%rbp)
leaq -0x3b(%rbp), %rsi
callq 0x15620
jmp 0x31a53
movl -0x38(%rbp), %eax
andl $0x1, %eax
movl %eax, -0x34(%rbp)
movl $0x5, -0x30(%rbp)
jmp 0x31ad0
movl -0x34(%rbp), %eax
shll $0x5, %eax
orl -0x38(%rbp), %eax
movl %eax, -0x34(%rbp)
movl $0x6, -0x30(%rbp)
jmp 0x31ad0
movq -0x50(%rbp), %rdi
movl -0x34(%rbp), %eax
shll $0x2, %eax
movl -0x38(%rbp), %ecx
shrl $0x3, %ecx
orl %ecx, %eax
movb %al, -0x3c(%rbp)
leaq -0x3c(%rbp), %rsi
callq 0x15620
jmp 0x31a9a
movl -0x38(%rbp), %eax
andl $0x7, %eax
movl %eax, -0x34(%rbp)
movl $0x7, -0x30(%rbp)
jmp 0x31ad0
movq -0x50(%rbp), %rdi
movl -0x34(%rbp), %eax
shll $0x5, %eax
movl -0x38(%rbp), %ecx
orl %ecx, %eax
movb %al, -0x3d(%rbp)
leaq -0x3d(%rbp), %rsi
callq 0x15620
jmp 0x31ac9
movl $0x0, -0x30(%rbp)
jmp 0x31934
cmpq $0x0, -0x18(%rbp)
je 0x31c65
movl -0x30(%rbp), %eax
movq %rax, -0x60(%rbp)
subq $0x7, %rax
ja 0x31c63
movq -0x60(%rbp), %rax
leaq 0x2868(%rip), %rcx      # 0x34364
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0x31c63
movq -0x18(%rbp), %rax
movb $0x1, (%rax)
jmp 0x31c63
cmpl $0x0, -0x34(%rbp)
jne 0x31b80
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3d, %eax
jne 0x31b80
movq -0x10(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x3d, %eax
jne 0x31b80
movq -0x10(%rbp), %rax
movsbl 0x2(%rax), %eax
cmpl $0x3d, %eax
jne 0x31b80
movq -0x10(%rbp), %rax
movsbl 0x3(%rax), %eax
cmpl $0x3d, %eax
jne 0x31b80
movq -0x10(%rbp), %rax
movsbl 0x4(%rax), %eax
cmpl $0x3d, %eax
jne 0x31b80
movq -0x10(%rbp), %rax
movsbl 0x5(%rax), %eax
cmpl $0x3d, %eax
jne 0x31b80
movq -0x10(%rbp), %rax
movzbl 0x6(%rax), %eax
movl %eax, %ecx
leaq 0x2836(%rip), %rax      # 0x343b0
cmpl $-0x1, (%rax,%rcx,4)
je 0x31b87
movq -0x18(%rbp), %rax
movb $0x1, (%rax)
jmp 0x31c63
cmpl $0x0, -0x34(%rbp)
jne 0x31bdc
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3d, %eax
jne 0x31bdc
movq -0x10(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x3d, %eax
jne 0x31bdc
movq -0x10(%rbp), %rax
movsbl 0x2(%rax), %eax
cmpl $0x3d, %eax
jne 0x31bdc
movq -0x10(%rbp), %rax
movsbl 0x3(%rax), %eax
cmpl $0x3d, %eax
jne 0x31bdc
movq -0x10(%rbp), %rax
movzbl 0x4(%rax), %eax
movl %eax, %ecx
leaq 0x27da(%rip), %rax      # 0x343b0
cmpl $-0x1, (%rax,%rcx,4)
je 0x31be3
movq -0x18(%rbp), %rax
movb $0x1, (%rax)
jmp 0x31c63
cmpl $0x0, -0x34(%rbp)
jne 0x31c28
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3d, %eax
jne 0x31c28
movq -0x10(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x3d, %eax
jne 0x31c28
movq -0x10(%rbp), %rax
movsbl 0x2(%rax), %eax
cmpl $0x3d, %eax
jne 0x31c28
movq -0x10(%rbp), %rax
movzbl 0x3(%rax), %eax
movl %eax, %ecx
leaq 0x278e(%rip), %rax      # 0x343b0
cmpl $-0x1, (%rax,%rcx,4)
je 0x31c2f
movq -0x18(%rbp), %rax
movb $0x1, (%rax)
jmp 0x31c63
cmpl $0x0, -0x34(%rbp)
jne 0x31c5a
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3d, %eax
jne 0x31c5a
movq -0x10(%rbp), %rax
movzbl 0x1(%rax), %eax
movl %eax, %ecx
leaq 0x275c(%rip), %rax      # 0x343b0
cmpl $-0x1, (%rax,%rcx,4)
je 0x31c61
movq -0x18(%rbp), %rax
movb $0x1, (%rax)
jmp 0x31c63
jmp 0x31c65
movb $0x1, -0x19(%rbp)
testb $0x1, -0x19(%rbp)
jne 0x31c78
movq -0x50(%rbp), %rdi
callq 0x15550
movq -0x48(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
movq -0x28(%rbp), %rdi
callq 0x47f0
nopl (%rax,%rax)