将十六进制字符转换为整数 - 有更好的方法吗?

发布于 2024-08-16 13:18:38 字数 1422 浏览 5 评论 0原文

我编写了一个函数来接收来自 Sirit IDentity MaX AVI 阅读器的数据并解析出设施代码和钥匙卡号码。我目前的做法是有效的,但是有更好的方法吗?看起来有点老套... buff & buf 的大小为 264

bufbuff 是 char

从阅读器接收的数据:

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
}

I have written a function to take in the data from a Sirit IDentity MaX AVI reader 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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仅此而已 2024-08-23 13:18:38

只需使用 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;
}

您也可以使用strtol 来自直接 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;
    }
}

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;
    }
}
蓦然回首 2024-08-23 13:18:38

这是获取所需数据的简单方法。我从事访问控制业务,所以这是我感兴趣的事情......

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
}

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
}
诠释孤独 2024-08-23 13:18:38

既然您已经在使用 sscanf,为什么不让它为您解析十六进制数字:

sscanf(buff, "%x %x", &val1, &val2);

Since you are already using sscanf, why not have it parse the hex numbers for you:

sscanf(buff, "%x %x", &val1, &val2);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文