blob: 19b9d53007f345863cff3ed0f6ee0b004e639f15 [file] [log] [blame]
/***************************************************************************************************************************************************************************************************************************
*
This file is part of CertiVox M-Pin Client and Server Libraries. *
The CertiVox M-Pin Client and Server Libraries provide developers with an extensive and efficient set of strong authentication and cryptographic functions. *
For further information about its features and functionalities please refer to http://www.certivox.com *
The CertiVox M-Pin Client and Server Libraries are free software: you can redistribute it and/or modify it under the terms of the BSD 3-Clause License http://opensource.org/licenses/BSD-3-Clause as stated below. *
The CertiVox M-Pin Client and Server Libraries are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
Note that CertiVox Ltd issues a patent grant for use of this software under specific terms and conditions, which you can find here: http://certivox.com/about-certivox/patents/ *
Copyright (c) 2013, CertiVox UK Ltd *
All rights reserved. *
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: *
� Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. *
� Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. *
� Neither the name of CertiVox UK Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. *
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, *
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS *
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE *
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*
***************************************************************************************************************************************************************************************************************************/
/*! \file CvXcode.cpp
\brief Base64 and Hex Encoding/Decoding facilities.
*- Project : SkyKey SDK
*- Authors : Mony Aladjem
*- Company : Certivox
*- Created : August 30, 2012, 4:43 PM
*- Last update : February 15, 2013
*- Platform : Windows XP SP3 - Windows 7
*- Dependency :
Base64 and Hex Encoding/Decoding facilities.
*/
#include "CvXcode.h"
using namespace std;
namespace CvShared
{
static const string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool IsBase64(unsigned char c)
{
return (isalnum(c) || (c == '+') || (c == '/'));
}
void CvBase64::Encode( const uint8_t* apBytesToEncode, int aLen, OUT std::string& aTarget )
{
int i = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
aTarget.clear();
while( aLen-- )
{
char_array_3[i++] = *(apBytesToEncode++);
if( i == 3 )
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for( i = 0; i < 4; i++ )
aTarget += base64_chars[char_array_4[i]];
i = 0;
}
}
if( i )
{
int j = 0;
for( j = i; j < 3; j++ )
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for( j = 0; j < i + 1; j++ )
aTarget += base64_chars[char_array_4[j]];
while( i++ < 3 )
aTarget += '=';
}
}
void CvBase64::Decode( const string& aSource, OUT string& aTarget )
{
int in_len = (int)aSource.size();
int i = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
aTarget.clear();
while( in_len-- && aSource[in_] != '=' && IsBase64(aSource[in_]) )
{
char_array_4[i++] = aSource[in_];
in_++;
if( i == 4 )
{
for( i = 0; i < 4; i++ )
char_array_4[i] = (unsigned char)base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for( i = 0; i < 3; i++ )
aTarget += char_array_3[i];
i = 0;
}
}
if( i )
{
int j = 0;
for( j = i; j < 4; j++ )
char_array_4[j] = 0;
for( j = 0; j < 4; j++ )
char_array_4[j] = (unsigned char)base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for( j = 0; j < i - 1; j++ )
aTarget += char_array_3[j];
}
}
static const char* hex_chars = "0123456789abcdef";
void CvHex::Encode( const uint8_t* apBytesToEncode, int aLen, OUT string& aTarget )
{
aTarget.clear();
for ( int i = 0; i < aLen; i++ )
{
char c1 = hex_chars[ apBytesToEncode[i] >> 4 ]; // High nibble
char c2 = hex_chars[ apBytesToEncode[i] & 0x0F ]; // Low nibble
aTarget += c1;
aTarget += c2;
}
}
void CvHex::Decode( const string& aSource, OUT string& aTarget )
{
aTarget.resize( aSource.length()/2 );
for ( size_t i = 0; i < aSource.length(); ++i )
{
// High nibble
char c = tolower( aSource[i] );
uint8_t nibble = 0;
switch( c )
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
nibble = c - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
nibble = c - 'a' + 0xA;
break;
}
if ( i%2 == 0 )
aTarget[i/2] = ( nibble << 4 );
else
aTarget[i/2] |= nibble;
}
}
}