164 lines
5.6 KiB
C++
164 lines
5.6 KiB
C++
/*! @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 */
|
|
//@{
|
|
|
|
#define CRYPTOLOG_QUOTE(X) CRYPTOLOG_QUOTE2(X)
|
|
#define CRYPTOLOG_QUOTE2(X) #X
|
|
#if __GNUC__ >= 2
|
|
# define CRYPTOLOG_END " -- "<<__PRETTY_FUNCTION__<<std::endl
|
|
#else
|
|
# define CRYPTOLOG_END std::endl
|
|
#endif
|
|
|
|
// Logging, enable with -DDEBUG
|
|
#ifndef CRYPTOLOG
|
|
# ifndef DEBUG
|
|
# define CRYPTOLOG(X)
|
|
# else
|
|
# include <iostream>
|
|
# define CRYPTOLOG(X) { \
|
|
std::string file(__FILE__); \
|
|
std::string line(CRYPTOLOG_QUOTE(__LINE__)); \
|
|
std::string::size_type pos(file.rfind('/')); \
|
|
if (pos!=std::string::npos) file=file.substr(pos+1); \
|
|
std::string spc1(18>file.size()?std::string(18-file.size(), ' ') \
|
|
:std::string()); \
|
|
std::string spc2(4>line.size()?std::string(4-line.size(), ' ') \
|
|
:std::string()); \
|
|
std::clog<<"CRYPTO: "<<spc1<<file<<':'<<spc2<<line<<" -- "<<X \
|
|
<<CRYPTOLOG_END; \
|
|
}
|
|
# endif
|
|
#endif
|
|
|
|
// Verbose logging, use with care, will also log PINs.
|
|
// Enable with -DDEBUG -DVERBOSE
|
|
#ifndef CRYPTOLOG_VERBOSE
|
|
# if !(defined(DEBUG)&&defined(VERBOSE))
|
|
# define CRYPTOLOG_VERBOSE(X)
|
|
# else
|
|
# include <iostream>
|
|
# define CRYPTOLOG_VERBOSE(X) { \
|
|
std::string file(__FILE__); \
|
|
std::string line(CRYPTOLOG_QUOTE(__LINE__)); \
|
|
std::string::size_type pos(file.rfind('/')); \
|
|
if (pos!=std::string::npos) file=file.substr(pos+1); \
|
|
std::string spc1(18>file.size()?std::string(18-file.size(), ' ') \
|
|
:std::string()); \
|
|
std::string spc2(4>line.size()?std::string(4-line.size(), ' ') \
|
|
:std::string()); \
|
|
std::clog<<"CRYPTO: "<<spc1<<file<<':'<<spc2<<line<<" -- "<<X \
|
|
<<CRYPTOLOG_END; \
|
|
}
|
|
# endif
|
|
#endif
|
|
|
|
//! @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
|