modp_b64w.c
size_t modp_b64w_decode(char* dest, const char* src, size_t len)
{
    size_t i;
    size_t leftover;
    size_t chunks;

    uint8_t* p;
    uint8_t* q;
    uint32_t x;
    uint32_t* destInt;
    const uint32_t* srcInt;
    uint32_t y;

    if (len == 0)
        return 0;

#ifdef DOPAD
    /*
     * if padding is used, then the message must be at least
     * 4 chars and be a multiple of 4
     */
    if (len < 4 || (len % 4 != 0)) {
        return (size_t)-1; /* error */
    }
    /* there can be at most 2 pad chars at the end */
    if (src[len - 1] == CHARPAD) {
        len--;
        if (src[len - 1] == CHARPAD) {
            len--;
        }
    }
#endif

    leftover = len % 4;
    chunks = (leftover == 0) ? len / 4 - 1 : len / 4;

    p = (uint8_t*)dest;
    x = 0;
    destInt = (uint32_t*)p;
    srcInt = (const uint32_t*)src;
    for (i = 0; i < chunks; ++i) {
        y = *srcInt;
        x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff];

        if (x >= BADCHAR) {
            return (size_t)-1;
        }
        *destInt = x;
        p += 3;
        destInt = (uint32_t*)p;
        srcInt++;
    }

    switch (leftover) {
    case 0:
        y = *srcInt;
        x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff];

        if (x >= BADCHAR) {
            return (size_t)-1;
        }
        *p++ = ((uint8_t*)(&x))[0];
        *p++ = ((uint8_t*)(&x))[1];
        *p = ((uint8_t*)(&x))[2];
        return (chunks + 1) * 3;

#ifndef DOPAD
    case 1: /* with padding this is an impossible case */
        q = (uint8_t*)srcInt;
        x = d0[*q];
        *p = *((uint8_t*)(&x)); /* i.e. first char/byte in int */
        break;
#endif
    case 2: /* case 2, 1  output byte */
        q = (uint8_t*)srcInt;
        x = d0[*q] | d1[*(q+1)];
        *p = *((uint8_t*)(&x)); /* i.e. first char */
        break;
    default: /* case 3, 2 output bytes */
        q = (uint8_t*)srcInt;
        x = d0[*q] | d1[*(q+1)] | d2[*(q+2)]; /* 0x3c */
        *p++ = ((uint8_t*)(&x))[0];
        *p = ((uint8_t*)(&x))[1];
        break;
    }

    if (x >= BADCHAR) {
        return (size_t)-1;
    }

    return 3 * chunks + (6 * leftover) / 8;
}
/* LITTLE  ENDIAN -- INTEL AND FRIENDS */
LITTLE  ENDIAN -- INTEL AND FRIENDS
LITTLE ENDIAN -- INTEL AND FRIENDS
size_t modp_b64w_decode(char* dest, const char* src, size_t len)
{
    size_t i;
    size_t leftover;
    size_t chunks;
    uint8_t* p;
    uint8_t* q;
    uint32_t x;
    uint32_t* destInt;
    const uint32_t* srcInt;
    uint32_t y;
    if (len == 0)
        return 0;
#ifdef DOPAD
    if (len < 4 || (len % 4 != 0)) {
        return (size_t)-1; 
    }
    if (src[len - 1] == CHARPAD) {
        len--;
        if (src[len - 1] == CHARPAD) {
            len--;
        }
    }
#endif
    leftover = len % 4;
    chunks = (leftover == 0) ? len / 4 - 1 : len / 4;
    p = (uint8_t*)dest;
    x = 0;
    destInt = (uint32_t*)p;
    srcInt = (const uint32_t*)src;
    for (i = 0; i < chunks; ++i) {
        y = *srcInt;
        x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff];
        if (x >= BADCHAR) {
            return (size_t)-1;
        }
        *destInt = x;
        p += 3;
        destInt = (uint32_t*)p;
        srcInt++;
    }
    switch (leftover) {
    case 0:
        y = *srcInt;
        x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff];
        if (x >= BADCHAR) {
            return (size_t)-1;
        }
        *p++ = ((uint8_t*)(&x))[0];
        *p++ = ((uint8_t*)(&x))[1];
        *p = ((uint8_t*)(&x))[2];
        return (chunks + 1) * 3;
#ifndef DOPAD
    case 1: 
        q = (uint8_t*)srcInt;
        x = d0[*q];
        *p = *((uint8_t*)(&x)); 
        break;
#endif
    case 2: 
        q = (uint8_t*)srcInt;
        x = d0[*q] | d1[*(q+1)];
        *p = *((uint8_t*)(&x)); 
        break;
    default: 
        q = (uint8_t*)srcInt;
        x = d0[*q] | d1[*(q+1)] | d2[*(q+2)]; 
        *p++ = ((uint8_t*)(&x))[0];
        *p = ((uint8_t*)(&x))[1];
        break;
    }
    if (x >= BADCHAR) {
        return (size_t)-1;
    }
    return 3 * chunks + (6 * leftover) / 8;
}
size_t modp_b64w_decode ( char * dest , const char * src , size_t len ) { size_t i ; size_t leftover ; size_t chunks ; uint8_t * p ; uint8_t * q ; uint32_t x ; uint32_t * destInt ; const uint32_t * srcInt ; uint32_t y ; if ( len == 0 ) return 0 ; #ifdef DOPAD if ( len < 4 || ( len % 4 != 0 ) ) { return ( size_t ) -1 ; } if ( src [ len - 1 ] == CHARPAD ) { len -- ; if ( src [ len - 1 ] == CHARPAD ) { len -- ; } } #endif leftover = len % 4 ; chunks = ( leftover == 0 ) ? len / 4 - 1 : len / 4 ; p = ( uint8_t * ) dest ; x = 0 ; destInt = ( uint32_t * ) p ; srcInt = ( const uint32_t * ) src ; for ( i = 0 ; i < chunks ; ++ i ) { y = * srcInt ; x = d0 [ y & 0xff ] | d1 [ ( y >> 8 ) & 0xff ] | d2 [ ( y >> 16 ) & 0xff ] | d3 [ ( y >> 24 ) & 0xff ] ; if ( x >= BADCHAR ) { return ( size_t ) -1 ; } * destInt = x ; p += 3 ; destInt = ( uint32_t * ) p ; srcInt ++ ; } switch ( leftover ) { case 0 : y = * srcInt ; x = d0 [ y & 0xff ] | d1 [ ( y >> 8 ) & 0xff ] | d2 [ ( y >> 16 ) & 0xff ] | d3 [ ( y >> 24 ) & 0xff ] ; if ( x >= BADCHAR ) { return ( size_t ) -1 ; } * p ++ = ( ( uint8_t * ) ( & x ) ) [ 0 ] ; * p ++ = ( ( uint8_t * ) ( & x ) ) [ 1 ] ; * p = ( ( uint8_t * ) ( & x ) ) [ 2 ] ; return ( chunks + 1 ) * 3 ; #ifndef DOPAD case 1 : q = ( uint8_t * ) srcInt ; x = d0 [ * q ] ; * p = * ( ( uint8_t * ) ( & x ) ) ; break ; #endif case 2 : q = ( uint8_t * ) srcInt ; x = d0 [ * q ] | d1 [ * ( q + 1 ) ] ; * p = * ( ( uint8_t * ) ( & x ) ) ; break ; default : q = ( uint8_t * ) srcInt ; x = d0 [ * q ] | d1 [ * ( q + 1 ) ] | d2 [ * ( q + 2 ) ] ; * p ++ = ( ( uint8_t * ) ( & x ) ) [ 0 ] ; * p = ( ( uint8_t * ) ( & x ) ) [ 1 ] ; break ; } if ( x >= BADCHAR ) { return ( size_t ) -1 ; } return 3 * chunks + ( 6 * leftover ) / 8 ; }
LITTLE  ENDIAN -- INTEL AND FRIENDS
LITTLE ENDIAN -- INTEL AND FRIENDS
/*
     * if padding is used, then the message must be at least
     * 4 chars and be a multiple of 4
     */ /* error */ /* there can be at most 2 pad chars at the end */ /* with padding this is an impossible case */ /* i.e. first char/byte in int */ /* case 2, 1  output byte */ /* i.e. first char */ /* case 3, 2 output bytes */ /* 0x3c */