/*! @file
@ id $ Id $
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
# ifndef __CRYPTAUX_HXX__
# define __CRYPTAUX_HXX__
# include <string>
# include <sstream>
# include <iomanip>
# include <stdexcept>
# include <algorithm>
/*! @defgroup gcrypto Auxiliary Crypto-Functions */
//@{
//! @see gcrypto
namespace crypto {
static const std : : string LETTER_CHARS
( " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " ) ;
static const std : : string NUMBER_CHARS
( " 0123456789 " ) ;
//! Contains @c @ in addition to standard characters.
static const std : : string GRAFIC_CHARS
( " ! \" #%&'()*+,-./:;<=>?[ \\ ]^_{|}~@ " ) ;
static const std : : string BLANK_CHARS
( " " ) ;
static const std : : string VALID_CHARS
( LETTER_CHARS + NUMBER_CHARS + GRAFIC_CHARS + BLANK_CHARS ) ;
inline std : : string hex ( const std : : string & data ) {
std : : stringstream res ;
for ( std : : string : : const_iterator it ( data . begin ( ) ) ; it ! = data . end ( ) ; + + it )
res < < std : : hex < < std : : setfill ( ' 0 ' ) < < std : : setw ( 2 )
< < ( unsigned int ) ( unsigned char ) * it ;
return res . str ( ) ;
}
inline std : : string hexTxt ( const std : : string & data ,
std : : string : : size_type len = 20 ) {
std : : stringstream res ;
std : : string : : size_type pos ( 0 ) ;
for ( std : : string : : const_iterator it ( data . begin ( ) ) ; it ! = data . end ( ) ; + + it ) {
res < < std : : hex < < std : : setfill ( ' 0 ' ) < < std : : setw ( 2 )
< < ( unsigned int ) ( unsigned char ) * it ;
+ + pos ;
if ( pos % len = = 0 | | pos = = data . size ( ) ) {
res < < std : : string ( 2 * ( len - ( pos - 1 ) % len ) , ' ' ) ;
for ( std : : string : : size_type i ( pos - ( pos - 1 ) % len - 1 ) ; i < pos ; + + i )
res < < ( VALID_CHARS . find ( data [ i ] ) = = std : : string : : npos ? ' . ' : data [ i ] ) ;
if ( pos ! = data . size ( ) ) res < < std : : endl ;
}
}
return res . str ( ) ;
}
inline std : : string readable ( const std : : string & data ,
std : : string : : size_type len = 20 ) {
if ( ! data . size ( ) )
return " <empty> " ;
else if ( data . find_first_not_of ( VALID_CHARS ) < data . size ( ) )
return hexTxt ( data ) ;
else
return " \" " + data + " \" " ;
}
//! Convert binary to readable hexadecimal
inline std : : string binToHex ( char c ) {
std : : stringstream ss ;
ss < < std : : hex < < std : : setw ( 2 ) < < std : : setfill ( ' 0 ' )
< < ( unsigned int ) ( unsigned char ) ( c ) ;
return ss . str ( ) ;
}
//! Convert binary to readable hexadecimal
inline std : : string binToHex ( const std : : string & s ) {
std : : string result ;
for ( std : : string : : const_iterator c ( s . begin ( ) ) ; c ! = s . end ( ) ; + + c )
result + = binToHex ( * c ) ;
return result ;
}
//! Convert readable lowercase hexadecimal to binary
inline std : : string hexToBin ( std : : string s ) {
const static std : : string HEX ( " 0123456789abcdef " ) ;
std : : transform ( s . begin ( ) , s . end ( ) , s . begin ( ) , : : tolower ) ;
if ( s . size ( ) % 2 )
throw std : : runtime_error
( " input string \" " + s
+ " \" must have an even number of hexadecimal numbers " ) ;
if ( s . find_first_not_of ( HEX ) ! = std : : string : : npos )
throw std : : runtime_error
( " input string \" " + s + " \" has non hexadecimal value at position "
+ ( ( std : : stringstream & ) ( std : : stringstream ( )
< < s . find_first_not_of ( HEX ) ) ) . str ( ) ) ;
std : : string res ;
for ( std : : string : : const_iterator it ( s . begin ( ) ) ; it ! = s . end ( ) ; + + it ) {
unsigned char c ( HEX . find ( * it ) ) ;
if ( + + it ! = s . end ( ) ) ( c < < = 4 ) + = HEX . find ( * it ) ;
res + = std : : string ( 1 , ( char ) c ) ;
}
return res ;
}
}
//@}
# endif