/*----------------------------------------------------------------
* base64_bin_to_ascii.c
*
* This source code is double license under:
* The MIT License (X11 License)
* Apache License, Version 2.0
*
* Copyright (c) 2013-2013 elf17 chobitprogram.blogspot.com All Rights Reserved.
----------------------------------------------------------------*/
/*----------------------------------------------------------------
* The MIT License (MIT)
* Copyright (c) 2013-2013 elf17 chobitprogram.blogspot.com
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------*/
/*----------------------------------------------------------------
* Copyright elf17 chobitprogram.blogspot.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
----------------------------------------------------------------*/
/**
* convert 3 bytes binary to 4 bytes ascii + NULL terminator by base64.
* @return status
* @retval -1 : error charactor is found.
* @retval 0 : success.
* @retval 1 : detect end of data.
* @see l64a()
*/
int b64a(const unsigned char * src, int len, unsigned char * dst)
{
int ret = 0; /* return code */
static const unsigned char b64str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char s[4] = {0}; /* src 8 bits + NULL terminator */
unsigned char d[5] = {0}; /* dst 6 bits + NULL terminator */
unsigned char f[4] = {1,1,1,1}; /* dst flag. true if src not exist. */
int i = 0; /* loop counter */
if ( len == 0 ) {
dst[0] = 0; /* NULL terminator */
ret = 1; /* detect end of data */
} else {
if ( len >= 1 ) { s[0] = src[0];
f[0] = 0; f[1] = 0; }
if ( len >= 2 ) { s[1] = src[1];
f[1] = 0; f[2] = 0; }
if ( len >= 3 ) { s[2] = src[2];
f[2] = 0; f[3] = 0; }
d[0] = (( s[0] & 0xfc ) >> 2);
d[1] = (( s[0] & 0x03 ) << 4) | (( s[1] & 0xf0 ) >> 4 );
d[2] = (( s[1] & 0x0f ) << 2) | (( s[2] & 0xc0 ) >> 6 );
d[3] = (( s[2] & 0x3f ) );
for ( i = 0 ; i < 4 ; i++ ) {
if ( f[i] != 0 ) { /* src not exist */
dst[i] = '='; /* NULL terminator */
ret = 1; /* detect end of data */
/* no break ... output is always (4+1) bytes. */
} else if ( d[i] >= 64 ) { /* error data */
dst[i] = 0; /* NULL terminator */
ret = -1; /* error data */
break;
} else {
dst[i] = b64str[d[i]]; /* convert to base64 string */
}
}
}
dst[4] = 0; /* NULL terminator */
return ret;
}
/**
* convert binary to ascii by base64.
* @return status
* @retval -1 : error charactor is found.
* @retval 0 : success.
* @see l64a(), b64a()
*/
int base64_bin_to_ascii(const unsigned char * src, int len, unsigned char * dst)
{
int ret = 0; /* return code */
const unsigned char * s = src;
unsigned char * d = dst;
int i = 0; /* loop counter */
for ( i = 0 ; i < len ; i += 3, s += 3, d += 4 ) {
ret = b64a( s, (len - i), d );
if ( ret != 0 ) {
break;
}
}
/* if error */
if ( ret < 0 ) {
dst[0] = 0;
} else if ( ret > 0 ) {
ret = 0;
}
return ret;
}