• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 
16 #include "utils.h"
17 #include <cstdlib>
18 #include <cstring>
19 #include <fstream>
20 #include <securec.h>
21 #include <sstream>
22 #include <sys/time.h>
23 #include <thread>
24 #include "common/common_macro.h"
25 #include "common/media_log.h"
26 
27 namespace OHOS {
28 namespace Sharing {
29 constexpr int IP_LEN = 64;
30 constexpr uint32_t MIN_DEVICE_ID_LEN = 10;
31 constexpr uint32_t MAC_LEN = 17;
32 constexpr uint32_t DEVICE_ID_VISIBLE_LEN = 5;
33 
GetThreadId()34 unsigned long long GetThreadId()
35 {
36     std::thread::id tid = std::this_thread::get_id();
37     std::stringstream buf;
38     buf << tid;
39     std::string stid = buf.str();
40     return std::stoull(stid);
41 }
42 
Split(const std::string & s,const char * delim)43 std::vector<std::string> Split(const std::string &s, const char *delim)
44 {
45     std::vector<std::string> ret;
46     if (delim == nullptr) {
47         return ret;
48     }
49 
50     size_t last = 0;
51     auto index = s.find(delim, last);
52     while (index != std::string::npos) {
53         if (index - last > 0) {
54             ret.push_back(s.substr(last, index - last));
55         }
56         last = index + strlen(delim);
57         index = s.find(delim, last);
58     }
59     if (!s.size() || s.size() - last > 0) {
60         ret.push_back(s.substr(last));
61     }
62 
63     return ret;
64 }
65 
SplitOnce(const std::string & s,const char * delim)66 std::vector<std::string> SplitOnce(const std::string &s, const char *delim)
67 {
68     std::vector<std::string> ret;
69     if (delim == nullptr) {
70         return ret;
71     }
72     size_t last = 0;
73     auto index = s.find(delim, last);
74     if (index != std::string::npos) {
75         ret.push_back(s.substr(0, index));
76         ret.push_back(s.substr(index + 1));
77     } else {
78         ret.push_back(s);
79     }
80 
81     return ret;
82 }
83 
84 #define TRIM(s, chars)                                             \
85     do {                                                           \
86         std::string map(0xFF, '\0');                               \
87         for (auto &ch : (chars)) {                                 \
88             map[(unsigned char &)ch] = '\1';                       \
89         }                                                          \
90         while ((s).size() && map.at((unsigned char &)(s).back()))  \
91             (s).pop_back();                                        \
92         while ((s).size() && map.at((unsigned char &)(s).front())) \
93             (s).erase(0, 1);                                       \
94     } while (0)
95 
Trim(std::string & s,const std::string & chars)96 std::string &Trim(std::string &s, const std::string &chars)
97 {
98     TRIM(s, chars);
99     return s;
100 }
101 
Trim(std::string && s,const std::string & chars)102 std::string Trim(std::string &&s, const std::string &chars)
103 {
104     TRIM(s, chars);
105     return std::move(s);
106 }
107 
108 #define ADD_VECTOR_END(v, i) (v).push_back((i))
109 
LowerCase(std::string value)110 std::string LowerCase(std::string value)
111 {
112     return ChangeCase(value, true);
113 }
114 
UpperCase(std::string value)115 std::string UpperCase(std::string value)
116 {
117     return ChangeCase(value, false);
118 }
119 
LTrim(std::string & value)120 void LTrim(std::string &value)
121 {
122     std::string::size_type i = 0;
123     for (i = 0; i < value.length(); i++) {
124         if (value[i] != ' ' && value[i] != '\t' && value[i] != '\n' && value[i] != '\r')
125             break;
126     }
127     value = value.substr(i);
128 }
129 
RTrim(std::string & value)130 void RTrim(std::string &value)
131 {
132     int32_t i = 0;
133     for (i = (int32_t)value.length() - 1; i >= 0; i--) {
134         if (value[i] != ' ' && value[i] != '\t' && value[i] != '\n' && value[i] != '\r')
135             break;
136     }
137     value = value.substr(0, i + 1);
138 }
139 
Trim(std::string & value)140 void Trim(std::string &value)
141 {
142     LTrim(value);
143     RTrim(value);
144 }
145 
ChangeCase(const std::string & value,bool LowerCase)146 std::string ChangeCase(const std::string &value, bool LowerCase)
147 {
148     std::string newvalue(value);
149     for (std::string::size_type i = 0, l = newvalue.length(); i < l; ++i)
150         newvalue[i] = LowerCase ? static_cast<char>(tolower(newvalue[i])) : static_cast<char>(toupper(newvalue[i]));
151     return newvalue;
152 }
153 
Replace(std::string & target,std::string search,std::string replacement)154 void Replace(std::string &target, std::string search, std::string replacement)
155 {
156     if (search == replacement) {
157         return;
158     }
159 
160     if (search == "") {
161         return;
162     }
163 
164     std::string::size_type i = std::string::npos;
165     std::string::size_type lastPos = 0;
166     while ((i = target.find(search, lastPos)) != std::string::npos) {
167         target.replace(i, search.length(), replacement);
168         lastPos = i + replacement.length();
169     }
170 }
171 
Split(std::string str,std::string separator,std::vector<std::string> & result)172 void Split(std::string str, std::string separator, std::vector<std::string> &result)
173 {
174     result.clear();
175     std::string::size_type position = str.find(separator);
176     std::string::size_type lastPosition = 0;
177     uint32_t separatorLength = separator.length();
178 
179     while (position != str.npos) {
180         ADD_VECTOR_END(result, str.substr(lastPosition, position - lastPosition));
181         lastPosition = position + separatorLength;
182         position = str.find(separator, lastPosition);
183     }
184     ADD_VECTOR_END(result, str.substr(lastPosition, std::string::npos));
185 }
186 
GetCurrentMillisecond()187 uint64_t GetCurrentMillisecond()
188 {
189     struct timeval tv {
190     };
191     gettimeofday(&tv, nullptr);
192     return tv.tv_sec * 1000 + tv.tv_usec / 1000; // 1000: time base conversion.
193 }
194 
SwapEndian16(uint16_t value)195 uint16_t SwapEndian16(uint16_t value)
196 {
197     return (value & 0xff00) >> 8 | (value & 0x00ff) << 8; // 8: swap endian
198 }
199 
SwapEndian32(uint32_t value)200 uint32_t SwapEndian32(uint32_t value)
201 {
202     uint8_t res[4];
203     for (int i = 0; i < 4; ++i) {            // 4: swap endian
204         res[i] = ((uint8_t *)&value)[3 - i]; // 3: swap endian
205     }
206     return *(uint32_t *)res;
207 }
208 
SwapEndian64(uint64_t value)209 uint64_t SwapEndian64(uint64_t value)
210 {
211     uint8_t res[8];
212     for (int i = 0; i < 8; ++i) {            // 8: swap endian
213         res[i] = ((uint8_t *)&value)[7 - i]; // 7: swap endian
214     }
215     return *(uint64_t *)res;
216 }
217 
LoadBE16(const uint8_t * p)218 uint16_t LoadBE16(const uint8_t *p)
219 {
220     RETURN_INVALID_IF_NULL(p);
221     return SwapEndian16(*(uint16_t *)p);
222 }
223 
LoadBE24(const uint8_t * p)224 uint32_t LoadBE24(const uint8_t *p)
225 {
226     RETURN_INVALID_IF_NULL(p);
227     uint8_t res[4] = {0, p[0], p[1], p[2]};
228     return SwapEndian32(*(uint32_t *)res);
229 }
230 
LoadBE32(const uint8_t * p)231 uint32_t LoadBE32(const uint8_t *p)
232 {
233     RETURN_INVALID_IF_NULL(p);
234     return SwapEndian32(*(uint32_t *)p);
235 }
236 
LoadBE64(const uint8_t * p)237 uint64_t LoadBE64(const uint8_t *p)
238 {
239     RETURN_INVALID_IF_NULL(p);
240     return SwapEndian64(*(uint64_t *)p);
241 }
242 
SetBE24(void * p,uint32_t val)243 void SetBE24(void *p, uint32_t val)
244 {
245     RETURN_IF_NULL(p);
246     uint8_t *data = (uint8_t *)p;
247     data[0] = val >> 16; // 16: byte offset
248     data[1] = val >> 8;  // 8: byte offset
249     data[2] = val;       // 2: transformed position
250 }
251 
SetBE32(void * p,uint32_t val)252 void SetBE32(void *p, uint32_t val)
253 {
254     RETURN_IF_NULL(p);
255     uint8_t *data = (uint8_t *)p;
256     data[3] = val;       // 3: transformed position
257     data[2] = val >> 8;  // 2: transformed position, 8: byte offset
258     data[1] = val >> 16; // 16: byte offset
259     data[0] = val >> 24; // 24: byte offset
260 }
261 
SetLE32(void * p,uint32_t val)262 void SetLE32(void *p, uint32_t val)
263 {
264     RETURN_IF_NULL(p);
265     uint8_t *data = (uint8_t *)p;
266     data[0] = val;
267     data[1] = val >> 8;  //  8: byte offset
268     data[2] = val >> 16; // 2: transformed position, 16: byte offset
269     data[3] = val >> 24; // 3: transformed position, 24: byte offset
270 }
271 
GetAnonyDevName(const std::string & value)272 std::string GetAnonyDevName(const std::string &value)
273 {
274     const size_t length = value.length();
275     const size_t keepHead = 2;
276     const size_t maxStars = 5;
277 
278     if (length <= keepHead) {
279         return std::string(length, '*');
280     }
281 
282     const size_t starCount = std::min(length - keepHead, maxStars);
283 
284     return value.substr(0, keepHead) + std::string(starCount, '*') +
285         (length > keepHead + starCount ? value.substr(keepHead + starCount) : "");
286 }
287 
GetAnonyString(const std::string & value)288 std::string GetAnonyString(const std::string &value)
289 {
290     constexpr size_t INT32_SHORT_ID_LENGTH = 20;
291     constexpr size_t INT32_MIN_ID_LENGTH = 3;
292     std::string result;
293     std::string tmpStr("******");
294     size_t strLen = value.length();
295     if (strLen < INT32_MIN_ID_LENGTH) {
296         return tmpStr;
297     }
298 
299     if (strLen <= INT32_SHORT_ID_LENGTH) {
300         result += value[0];
301         result += tmpStr;
302         result += value[strLen - 1];
303     } else {
304         constexpr size_t INT32_PLAINTEXT_LENGTH = 4;
305         result.append(value, 0, INT32_PLAINTEXT_LENGTH);
306         result += tmpStr;
307         result.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH);
308     }
309 
310     return result;
311 }
312 
GetLocalP2pAddress(const std::string & interface)313 std::string GetLocalP2pAddress(const std::string &interface)
314 {
315     if (interface.empty()) {
316         return "";
317     }
318 
319     int32_t socketFd = socket(AF_INET, SOCK_DGRAM, 0);
320     if (socketFd < 0) {
321         SHARING_LOGE("open socket failed, socketFd=%{public}d", socketFd);
322         return "";
323     }
324 
325     struct ifreq request;
326     if (strncpy_s(request.ifr_name, sizeof(request.ifr_name), interface.c_str(), interface.length()) != 0) {
327         SHARING_LOGE("copy netIfName:%s fail", interface.c_str());
328         close(socketFd);
329         return "";
330     }
331 
332     int32_t ret = ioctl(socketFd, SIOCGIFADDR, &request);
333     close(socketFd);
334     if (ret < 0) {
335         char errmsg[256] = {0};
336         strerror_r(errno, errmsg, sizeof(errmsg));
337         SHARING_LOGE("get ifr conf failed = %{public}d, error %{public}s", ret, errmsg);
338         return "";
339     }
340 
341     auto sockAddrIn = reinterpret_cast<sockaddr_in*>(&request.ifr_addr);
342     char ipString[IP_LEN] = {0};
343     if (inet_ntop(sockAddrIn->sin_family, &sockAddrIn->sin_addr, ipString, IP_LEN) == nullptr) {
344         SHARING_LOGE("inet_ntop failed");
345         return "";
346     }
347 
348     return std::string(ipString);
349 }
350 
GetAnonymousIp(const std::string & ip)351 std::string GetAnonymousIp(const std::string &ip)
352 {
353     if (ip.empty()) {
354         return "";
355     }
356     std::regex pattern(R"(^((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]|[*])\.){3}(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]|[*])$)");
357     if (!std::regex_match(ip, pattern)) {
358         return "";
359     }
360     return ip.substr(0, ip.find_last_of('.') + 1) + "***";
361 }
362 
GetAnonymousMAC(const std::string & mac)363 std::string GetAnonymousMAC(const std::string &mac)
364 {
365     if (mac.empty() || mac.length() != MAC_LEN) {
366         return "";
367     }
368     uint32_t maskPos[4] = {12, 13, 15, 16};
369     char marArr[mac.length() + 1];
370     if (memcpy_s(marArr, mac.length(), mac.c_str(), mac.length()) != 0) {
371         return "";
372     }
373 
374     for (size_t i = 0; i < sizeof(maskPos) / sizeof(maskPos[0]); i++) {
375         marArr[maskPos[i]] = '*';
376     }
377     return std::string(marArr);
378 }
379 
GetAnonymousDeviceId(const std::string & deviceId)380 std::string GetAnonymousDeviceId(const std::string &deviceId)
381 {
382     if (deviceId.empty() || deviceId.length() < MIN_DEVICE_ID_LEN) {
383         return "";
384     }
385     return deviceId.substr(0, DEVICE_ID_VISIBLE_LEN) + "**" +
386         deviceId.substr(deviceId.length() - DEVICE_ID_VISIBLE_LEN);
387 }
388 
ConvertSinAddrToStr(const struct sockaddr_in & addr)389 std::string ConvertSinAddrToStr(const struct sockaddr_in &addr)
390 {
391     char ipString[IP_LEN] = {0};
392     if (inet_ntop(addr.sin_family, &addr.sin_addr, ipString, IP_LEN) == nullptr) {
393         SHARING_LOGE("inet_ntop failed");
394         return "";
395     }
396     return std::string(ipString);
397 }
398 } // namespace Sharing
399 } // namespace OHOS
400