Convert Hex Char To Int - Is there a better way?
I have written a function to take in the data from a Sirit IDentity MaX AVI read开发者_如何学运维er and parse out the facility code and keycard number. How I am currently doing it works, but is there a better way? Seems little hackish... buff & buf are size 264
buf
and buff
are char
Data received from reader:
2009/12/30 14:56:18 epc0 LN:001 C80507A0008A19FA 0000232F Xlat'd
char TAccessReader::HexCharToInt(char n)
{
if (n >= '0' && n <= '9')
return (n-'0');
else
if (n >= 'A' && n <= 'F')
return (n-'A'+10);
else
return 0;
}
bool TAccessReader::CheckSirit(char *buf, long *key_num, unsigned char *fac) {
unsigned short i, j, k;
*key_num = 0; // Default is zero
memset(buff, 0, sizeof(buff));
i = sscanf(buf, "%s %s %s %s %s %s %s", &buff[0], &buff[20], &buff[40],
&buff[60], &buff[80], &buff[140], &buff[160]);
if (i == 7 && buff[147] && !buff[148]) {
// UUGGNNNN UU=spare, GG=Facility Code, NNNN=Keycard Number (all HEX)
// get facility code
*fac = HexCharToInt(buff[142]) * 16 + HexCharToInt(buff[143]);
*key_num = (unsigned short)HexCharToInt(buff[144]) * 4096 +
(unsigned short)HexCharToInt(buff[145]) * 256 +
(unsigned short)HexCharToInt(buff[146]) * 16 +
HexCharToInt(buff[147]);
}
// do some basic checks.. return true or false
}
Just use std::stringstream
:
#include <sstream>
#include <iostream>
using namespace std;
int main() {
unsigned int x;
stringstream ss;
ss << hex << "ff";
ss >> x;
// output it as a signed type
cout << static_cast<int>(x) << endl;
}
You can also use strtol
from straight-up C:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "ff";
char *p;
long n = strtol(s.c_str(), &p, 16);
if (*p != 0) {
cout << "fail" << endl;
}
else {
cout << n << endl;
}
}
Here's an easy way to get at the data you want. I do work in the access control business so this was something that interested me...
template<typename TRet, typename Iterator>
TRet ConvertHex(Iterator begin) {
unsigned long result;
Iterator end = begin + (sizeof(TRet) * 2);
std::stringstream ss(std::string(begin, end));
ss >> std::hex >> result;
return result;
}
bool TAccessReader::CheckSirit(char *buf, long *key_num, unsigned char *fac) {
*key_num = 0; // Default is zero
std::istringstream sbuf(std::string(buf, buf+264));
// Stuff all of the string elements into a vector
std::vector<std::string> elements;
std::copy (std::istream_iterator<std::string>(sbuf), std::istream_iterator<std::string>(), std::back_inserter (elements));
// We're interested in the 6th element
std::string read = elements[5];
if (read.length() == 8) {
// UUGGNNNN UU=spare, GG=Facility Code, NNNN=Keycard Number (all HEX)
// get facility and card code
std::string::const_iterator iter = read.begin();
*fac = ConvertHex<unsigned char>(iter + 2);
*key_num = ConvertHex<unsigned short>(iter + 4);
}
// do some basic checks.. return true or false
}
Since you are already using sscanf, why not have it parse the hex numbers for you:
sscanf(buff, "%x %x", &val1, &val2);
精彩评论