1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "nfc_sdk_common.h"
16 
17 #include <algorithm>
18 #include <sstream>
19 #include <securec.h>
20 #include <sys/time.h>
21 
22 #include "loghelper.h"
23 
24 namespace OHOS {
25 namespace NFC {
26 namespace KITS {
27 
IsLittleEndian()28 bool NfcSdkCommon::IsLittleEndian()
29 {
30     const char LAST_DATA_BYTE = 0x78;
31     union CheckData {
32         int x;
33         char y;
34     };
35 
36     union CheckData data;
37     data.x = 0x12345678;
38     if (data.y == LAST_DATA_BYTE) {
39         return true;
40     }
41     return false;
42 }
43 
BytesVecToHexString(const unsigned char * src,uint32_t length)44 std::string NfcSdkCommon::BytesVecToHexString(const unsigned char* src, uint32_t length)
45 {
46     std::string result = "";
47     if (length <= 0) {
48         return result;
49     }
50     const std::string hexKeys = "0123456789ABCDEF";
51     for (uint32_t i = 0; i < length; i++) {
52         result.push_back(hexKeys[(src[i] & 0xF0) >> HALF_BYTE_BITS]);
53         result.push_back(hexKeys[src[i] & 0x0F]);
54     }
55     return result;
56 }
57 
UnsignedCharToHexString(const unsigned char src)58 std::string NfcSdkCommon::UnsignedCharToHexString(const unsigned char src)
59 {
60     std::string result = "";
61     const std::string hexKeys = "0123456789ABCDEF";
62     result.push_back(hexKeys[(src & 0xF0) >> HALF_BYTE_BITS]);
63     result.push_back(hexKeys[src & 0x0F]);
64     return result;
65 }
66 
HexStringToBytes(const std::string & src,std::vector<unsigned char> & bytes)67 void NfcSdkCommon::HexStringToBytes(const std::string &src, std::vector<unsigned char> &bytes)
68 {
69     if (src.empty()) {
70         return;
71     }
72 
73     uint32_t bytesLen = src.length() / HEX_BYTE_LEN;
74     std::string strByte;
75     unsigned int srcIntValue;
76     for (uint32_t i = 0; i < bytesLen; i++) {
77         strByte = src.substr(i * HEX_BYTE_LEN, HEX_BYTE_LEN);
78         if (sscanf_s(strByte.c_str(), "%x", &srcIntValue) <= 0) {
79             ErrorLog("HexStringToBytes, sscanf_s failed.");
80             bytes.clear();
81             return;
82         }
83         bytes.push_back(static_cast<unsigned char>(srcIntValue & 0xFF));
84     }
85 }
86 
GetHexStrBytesLen(const std::string src)87 uint32_t NfcSdkCommon::GetHexStrBytesLen(const std::string src)
88 {
89     // 2 charactors consist of one byte.
90     if (src.empty()) {
91         return 0;
92     }
93     uint32_t length = src.length();
94     if (length % HEX_BYTE_LEN == 0) {
95         return (length / HEX_BYTE_LEN);
96     } else {
97         return ((length / HEX_BYTE_LEN) + 1);
98     }
99 }
100 
GetByteFromHexStr(const std::string src,uint32_t index)101 unsigned char NfcSdkCommon::GetByteFromHexStr(const std::string src, uint32_t index)
102 {
103     // 2 charactors consist of one byte.
104     if (src.empty() || (src.length() < index * HEX_BYTE_LEN + HEX_BYTE_LEN)) {
105         ErrorLog("GetByteFromHexStr, src length error.");
106         return 0;
107     }
108     std::string strByte = src.substr(index * HEX_BYTE_LEN, HEX_BYTE_LEN);
109     unsigned int srcIntValue;
110     if (sscanf_s(strByte.c_str(), "%x", &srcIntValue) <= 0) {
111         ErrorLog("GetByteFromHexStr, sscanf_s failed.");
112         return 0;
113     }
114     return static_cast<unsigned char>(srcIntValue & 0xFF);
115 }
116 
StringToInt(std::string src,bool bLittleEndian)117 uint32_t NfcSdkCommon::StringToInt(std::string src, bool bLittleEndian)
118 {
119     uint32_t value = 0;
120     if (bLittleEndian) {
121         for (size_t i = SHIFT_TIME; i > 0; i--) {
122             value += static_cast<uint32_t>((src.at(SHIFT_TIME - i)) << (i * SHIFT_SIZE - SHIFT_SIZE));
123         }
124     } else {
125         for (size_t i = 0; i < SHIFT_TIME; i++) {
126             value += static_cast<uint32_t>((src.at(i)) << (i * SHIFT_SIZE));
127         }
128     }
129     return value;
130 }
131 
IntToHexString(uint32_t num)132 std::string NfcSdkCommon::IntToHexString(uint32_t num)
133 {
134     std::stringstream ss;
135     ss << std::hex << num;
136     std::string result = ss.str();
137     transform(result.begin(), result.end(), result.begin(), ::toupper);
138     if (result.length() % HEX_BYTE_LEN > 0) { // expend "0" if string length is odd
139         result = "0" + result;
140     }
141     return result;
142 }
143 
StringToAsciiBytes(const std::string & src,std::vector<unsigned char> & bytes)144 void NfcSdkCommon::StringToAsciiBytes(const std::string &src, std::vector<unsigned char> &bytes)
145 {
146     if (src.empty()) {
147         return;
148     }
149     uint32_t bytesLen = src.length();
150     for (uint32_t i = 0; i < bytesLen; i++) {
151         unsigned int srcAsciiIntVal = static_cast<unsigned int>(src[i]);
152         bytes.push_back(static_cast<unsigned char>(srcAsciiIntVal & 0xFF));
153     }
154 }
155 
StringToHexString(const std::string & src)156 std::string NfcSdkCommon::StringToHexString(const std::string &src)
157 {
158     std::vector<unsigned char> bytes;
159     StringToAsciiBytes(src, bytes);
160     uint32_t len = src.length();
161     std::string result = BytesVecToHexString(&bytes[0], len);
162     return result;
163 }
164 
HexStringToAsciiString(const std::string & src)165 std::string NfcSdkCommon::HexStringToAsciiString(const std::string &src)
166 {
167     if (src.size() % HEX_BYTE_LEN != 0 || src.empty()) {  // 2 is Even number judgement
168         ErrorLog("HexStringToAsciiString length error");
169         return "";
170     }
171     std::string result = "";
172     for (size_t i = 0; i < src.size() / HEX_BYTE_LEN; i++) {
173         unsigned char byteVal = GetByteFromHexStr(src, i);
174         const char minPrintChar = ' ';
175         const char maxPrintChar = '~';
176         /* ' ' to '~' is the printable char range */
177         if (static_cast<char>(byteVal) < minPrintChar || static_cast<char>(byteVal) > maxPrintChar) {
178             return "";
179         }
180         result.push_back(static_cast<char>(byteVal));
181     }
182     return result;
183 }
184 
185 /*
186  * transfer Hex array to String without checking Ascii validation, compatible with Chinese characters
187  */
HexArrayToStringWithoutChecking(const std::string & src)188 std::string NfcSdkCommon::HexArrayToStringWithoutChecking(const std::string &src)
189 {
190     if (src.size() % HEX_BYTE_LEN != 0 || src.empty()) {  // 2 is Even number judgement
191         ErrorLog("HexStringToAsciiString length error");
192         return "";
193     }
194     std::string result = "";
195     for (size_t i = 0; i < src.size() / HEX_BYTE_LEN; i++) {
196         unsigned char byteVal = GetByteFromHexStr(src, i);
197         result.push_back(static_cast<char>(byteVal));
198     }
199     return result;
200 }
201 
GetCurrentTime()202 uint64_t NfcSdkCommon::GetCurrentTime()
203 {
204     // get the time since 1970/1/1
205     constexpr int timeRate = 1000;
206     struct timeval time = {0};
207     gettimeofday(&time, nullptr);
208     return static_cast<uint64_t>(time.tv_sec * timeRate + time.tv_usec / timeRate);
209 }
210 
GetRelativeTime()211 uint64_t NfcSdkCommon::GetRelativeTime()
212 {
213     // get the time since the system was booted
214     constexpr int64_t msPerSecond = 1000;
215     constexpr int64_t nsPerMs = 1000000;
216 
217     struct timespec times = {0};
218     clock_gettime(CLOCK_MONOTONIC, &times);
219     return ((times.tv_sec * msPerSecond) + (times.tv_nsec / nsPerMs));
220 }
221 
CodeMiddlePart(const std::string & src)222 std::string NfcSdkCommon::CodeMiddlePart(const std::string &src)
223 {
224     std::string res = "";
225     if (src.empty()) {
226         return res;
227     }
228     const char code = 'X';
229     const uint32_t maxStrLen = 1024;
230     uint32_t len = src.length();
231     if (len > maxStrLen) {
232         return res;
233     }
234 
235     uint32_t head = (len / 2) / 2; // Divide the string evenly into 2 * 2 parts
236     if (len <= head * 2) {  // The length of the head * 2 is greater than src
237         return src;
238     }
239     for (uint32_t i = 0; i < head; i++) {
240         res.push_back(src[i]);
241     }
242     for (uint32_t i = head; i < (len - head); i++) {
243         res.push_back(code);
244     }
245     for (uint32_t i = (len - head); i < len; i++) {
246         res.push_back(src[i]);
247     }
248     return res;
249 }
250 }  // namespace KITS
251 }  // namespace NFC
252 }  // namespace OHOS
253