CLewaimaiString.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. #include "pch.h"
  2. #include "CLewaimaiString.h"
  3. #include <boost/archive/iterators/base64_from_binary.hpp>
  4. #include <boost/archive/iterators/binary_from_base64.hpp>
  5. #include <boost/archive/iterators/transform_width.hpp>
  6. #include <string>
  7. #include <iostream>
  8. #include <sstream>
  9. using namespace boost::archive::iterators;
  10. unsigned char ToHex(unsigned char x)
  11. {
  12. return x > 9 ? x + 55 : x + 48;
  13. }
  14. unsigned char FromHex(unsigned char x)
  15. {
  16. unsigned char y;
  17. if(x >= 'A' && x <= 'Z')
  18. {
  19. y = x - 'A' + 10;
  20. }
  21. else if(x >= 'a' && x <= 'z')
  22. {
  23. y = x - 'a' + 10;
  24. }
  25. else if(x >= '0' && x <= '9')
  26. {
  27. y = x - '0';
  28. }
  29. else
  30. {
  31. assert(0);
  32. }
  33. return y;
  34. }
  35. CLewaimaiString::CLewaimaiString()
  36. {
  37. }
  38. CLewaimaiString::~CLewaimaiString()
  39. {
  40. }
  41. bool CLewaimaiString::base64_encode(const std::string& input, std::string* output)
  42. {
  43. typedef base64_from_binary<transform_width<std::string::const_iterator, 6, 8>> Base64EncodeIterator;
  44. std::stringstream result;
  45. try
  46. {
  47. copy(Base64EncodeIterator(input.begin()), Base64EncodeIterator(input.end()), std::ostream_iterator<char>(result));
  48. }
  49. catch(...)
  50. {
  51. return false;
  52. }
  53. size_t equal_count = (3 - input.length() % 3) % 3;
  54. for(size_t i = 0; i < equal_count; i++)
  55. {
  56. result.put('=');
  57. }
  58. *output = result.str();
  59. return output->empty() == false;
  60. }
  61. bool CLewaimaiString::base64_decode(const std::string& input, std::string* output)
  62. {
  63. typedef transform_width<binary_from_base64<std::string::const_iterator>, 8, 6> Base64DecodeIterator;
  64. std::stringstream result;
  65. try
  66. {
  67. copy(Base64DecodeIterator(input.begin()), Base64DecodeIterator(input.end()), std::ostream_iterator<char>(result));
  68. }
  69. catch(...)
  70. {
  71. return false;
  72. }
  73. *output = result.str();
  74. return output->empty() == false;
  75. }
  76. void CLewaimaiString::trim(std::string& s)
  77. {
  78. if(!s.empty())
  79. {
  80. s.erase(0, s.find_first_not_of(" "));
  81. s.erase(s.find_last_not_of(" ") + 1);
  82. }
  83. }
  84. std::string CLewaimaiString::UrlEncode(const std::string& str)
  85. {
  86. std::string strTemp = "";
  87. size_t length = str.length();
  88. for(size_t i = 0; i < length; i++)
  89. {
  90. if(isalnum((unsigned char)str[i]) ||
  91. (str[i] == '-') ||
  92. (str[i] == '_') ||
  93. (str[i] == '.') ||
  94. (str[i] == '~'))
  95. {
  96. strTemp += str[i];
  97. }
  98. else if(str[i] == ' ')
  99. {
  100. strTemp += "+";
  101. }
  102. else
  103. {
  104. strTemp += '%';
  105. strTemp += ToHex((unsigned char)str[i] >> 4);
  106. strTemp += ToHex((unsigned char)str[i] % 16);
  107. }
  108. }
  109. return strTemp;
  110. }
  111. std::string CLewaimaiString::UrlDecode(const std::string& str)
  112. {
  113. std::string strTemp = "";
  114. size_t length = str.length();
  115. for(size_t i = 0; i < length; i++)
  116. {
  117. if(str[i] == '+')
  118. {
  119. strTemp += ' ';
  120. }
  121. else if(str[i] == '%')
  122. {
  123. assert(i + 2 < length);
  124. unsigned char high = FromHex((unsigned char)str[++i]);
  125. unsigned char low = FromHex((unsigned char)str[++i]);
  126. strTemp += high * 16 + low;
  127. }
  128. else
  129. {
  130. strTemp += str[i];
  131. }
  132. }
  133. return strTemp;
  134. }
  135. std::string CLewaimaiString::UnicodeToUTF8(const std::wstring& wstr)
  136. {
  137. if (wstr.empty()) return {};
  138. int n = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
  139. if (n <= 0) return {}; // UTF-8 非法序列也会返回 0
  140. std::string result(n, 0); // 先留 null 位
  141. WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &result[0], n, nullptr, nullptr);
  142. result.resize(n - 1); // 去掉结尾 '\0'
  143. return result;
  144. }
  145. std::wstring CLewaimaiString::UTF8ToUnicode(const std::string& str)
  146. {
  147. if (str.empty()) return {};
  148. int n = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
  149. if (n <= 0) return {};
  150. std::wstring result(n, 0);
  151. MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &result[0], n);
  152. result.resize(n - 1);
  153. return result;
  154. }
  155. std::string CLewaimaiString::UnicodeToGBK(const std::wstring& wstr)
  156. {
  157. if (wstr.empty()) return {};
  158. int n = WideCharToMultiByte(936, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
  159. if (n <= 0) return {}; // 转换失败保护
  160. std::string result(n, 0); // 先留 null 的位置
  161. WideCharToMultiByte(936, 0, wstr.c_str(), -1, &result[0], n, nullptr, nullptr);
  162. result.resize(n - 1); // 去掉结尾 '\0',size 准确
  163. return result;
  164. }
  165. std::wstring CLewaimaiString::GBKToUnicode(const std::string& src)
  166. {
  167. if (src.empty()) return {};
  168. int n = MultiByteToWideChar(936, 0, src.c_str(), -1, nullptr, 0);
  169. if (n <= 0) return {};
  170. std::wstring result(n, 0);
  171. MultiByteToWideChar(936, 0, src.c_str(), -1, &result[0], n);
  172. result.resize(n - 1);
  173. return result;
  174. }
  175. std::string CLewaimaiString::UTF8ToGBK(const std::string& str)
  176. {
  177. std::wstring wsUnicode = CLewaimaiString::UTF8ToUnicode(str);
  178. std::string sGBK = CLewaimaiString::UnicodeToGBK(wsUnicode);
  179. return sGBK;
  180. }
  181. std::string CLewaimaiString::GBKToUTF8(const std::string& str)
  182. {
  183. std::wstring wsUnicode = CLewaimaiString::GBKToUnicode(str);
  184. std::string sUtf8 = CLewaimaiString::UnicodeToUTF8(wsUnicode);
  185. return sUtf8;
  186. }
  187. std::string CLewaimaiString::DoubleToString(const double value, unsigned int precisionAfterPoint)
  188. {
  189. char str[256];
  190. std::string pre = "%." + std::to_string(precisionAfterPoint) + "f";
  191. sprintf_s(str, pre.c_str(), value);
  192. std::string result = str;
  193. return result;
  194. }
  195. bool CLewaimaiString::isIPAddressValid(const char* pszIPAddr)
  196. {
  197. if(!pszIPAddr)
  198. {
  199. return false; //若pszIPAddr为空
  200. }
  201. char IP1[100], cIP[4];
  202. int len = strlen(pszIPAddr);
  203. int i = 0, j = len - 1;
  204. int k, m = 0, n = 0, num = 0;
  205. //去除首尾空格(取出从i-1到j+1之间的字符):
  206. while(pszIPAddr[i++] == ' ');
  207. while(pszIPAddr[j--] == ' ');
  208. for(k = i - 1; k <= j + 1; k++)
  209. {
  210. IP1[m++] = *(pszIPAddr + k);
  211. }
  212. IP1[m] = '\0';
  213. char* p = IP1;
  214. while(*p != '\0')
  215. {
  216. if(*p == ' ' || *p < '0' || *p > '9')
  217. {
  218. return false;
  219. }
  220. cIP[n++] = *p; //保存每个子段的第一个字符,用于之后判断该子段是否为0开头
  221. int sum = 0; //sum为每一子段的数值,应在0到255之间
  222. while(*p != '.' && *p != '\0')
  223. {
  224. if(*p == ' ' || *p < '0' || *p > '9')
  225. {
  226. return false;
  227. }
  228. sum = sum * 10 + *p - 48; //每一子段字符串转化为整数
  229. p++;
  230. }
  231. if(*p == '.')
  232. {
  233. if((*(p - 1) >= '0' && *(p - 1) <= '9') && (*(p + 1) >= '0' && *(p + 1) <= '9')) //判断"."前后是否有数字,若无,则为无效IP,如“1.1.127.”
  234. {
  235. num++; //记录“.”出现的次数,不能大于3
  236. }
  237. else
  238. {
  239. return false;
  240. }
  241. };
  242. if((sum > 255) || (sum > 0 && cIP[0] == '0') || num > 3)
  243. {
  244. return false; //若子段的值>255或为0开头的非0子段或“.”的数目>3,则为无效IP
  245. }
  246. if(*p != '\0')
  247. {
  248. p++;
  249. }
  250. n = 0;
  251. }
  252. if(num != 3)
  253. {
  254. return false;
  255. }
  256. return true;
  257. }
  258. /*
  259. * 把字符串in 以 delim为分隔符,转化为vector,比如 1,2,3,4,5,用逗号分隔,转化为5个元素的vector
  260. */
  261. std::vector<std::string> CLewaimaiString::Split(const std::string& in, const std::string& delim)
  262. {
  263. std::vector<std::string> ret;
  264. if (in == "")
  265. {
  266. //空字符串,直接返回空vector
  267. return ret;
  268. }
  269. try
  270. {
  271. std::regex re{ delim };
  272. return std::vector<std::string>
  273. {
  274. std::sregex_token_iterator(in.begin(), in.end(), re, -1),
  275. std::sregex_token_iterator()
  276. };
  277. }
  278. catch(const std::exception& e)
  279. {
  280. std::cout << "error:" << e.what() << std::endl;
  281. }
  282. return ret;
  283. }
  284. std::string CLewaimaiString::Merge(const std::vector<std::string>& in, const std::string& delim)
  285. {
  286. std::string ret = "";
  287. for (size_t i = 0; i < in.size(); i++)
  288. {
  289. ret += in[i];
  290. if (i < in.size() - 1)
  291. {
  292. ret += delim;
  293. }
  294. }
  295. return ret;
  296. }
  297. /*
  298. *nNum是表示替换几个,默认为1表示替换第1个
  299. **/
  300. int CLewaimaiString::Replace(std::wstring& strContent, std::wstring strReplace, std::wstring strDest, int nNum)
  301. {
  302. int nCount = 0;
  303. while(true)
  304. {
  305. size_t pos = strContent.find(strReplace);
  306. if(pos != std::wstring::npos)
  307. {
  308. WCHAR pBuf[1] = { L'\0' };
  309. strContent.replace(pos, strReplace.length(), pBuf, 0);
  310. strContent.insert(pos, strDest);
  311. nCount++;
  312. if(nCount == nNum)
  313. {
  314. break;
  315. }
  316. }
  317. else
  318. {
  319. break;
  320. }
  321. }
  322. return 0;
  323. }
  324. //整个替换所有的字符串,把strBig钟的strsrc全部替换成strdst
  325. void CLewaimaiString::string_replace(std::string &strBig, const std::string &strsrc, const std::string &strdst)
  326. {
  327. std::string::size_type pos = 0;
  328. std::string::size_type srclen = strsrc.size();
  329. std::string::size_type dstlen = strdst.size();
  330. while ((pos = strBig.find(strsrc, pos)) != std::string::npos)
  331. {
  332. strBig.replace(pos, srclen, strdst);
  333. pos += dstlen;
  334. }
  335. }
  336. //从文件路径或者url中获取文件名
  337. std::string CLewaimaiString::GetFilenameFromUrl(std::string url)
  338. {
  339. if (url.empty()) return std::string();
  340. // 截取掉查询字符串和片段标识
  341. size_t end = url.find_first_of("?#");
  342. if (end == std::string::npos) end = url.size();
  343. // 找到最后一个 '/',取其后面的部分作为文件名
  344. size_t pos = (end == 0) ? std::string::npos : url.find_last_of('/', end - 1);
  345. size_t start = (pos == std::string::npos) ? 0 : pos + 1;
  346. if (start >= end) return std::string();
  347. std::string name = url.substr(start, end - start);
  348. // 对 %XX 编码进行解码(返回 UTF-8 字节序列)
  349. auto hexVal = [](char c) -> int
  350. {
  351. if (c >= '0' && c <= '9') return c - '0';
  352. if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
  353. if (c >= 'A' && c <= 'F') return 10 + (c - 'A');
  354. return -1;
  355. };
  356. std::string decoded;
  357. decoded.reserve(name.size());
  358. for (size_t i = 0; i < name.size(); ++i)
  359. {
  360. char c = name[i];
  361. if (c == '%' && i + 2 < name.size())
  362. {
  363. int hi = hexVal(name[i + 1]);
  364. int lo = hexVal(name[i + 2]);
  365. if (hi != -1 && lo != -1)
  366. {
  367. char ch = static_cast<char>((hi << 4) | lo);
  368. decoded.push_back(ch);
  369. i += 2;
  370. continue;
  371. }
  372. }
  373. decoded.push_back(c);
  374. }
  375. return decoded;
  376. }
  377. //得到文件路径的目录
  378. std::string CLewaimaiString::GetPathDir(std::string filePath)
  379. {
  380. std::string dirPath = filePath;
  381. size_t p = filePath.find_last_of(L'\\');
  382. if (p != -1)
  383. {
  384. dirPath.erase(p);
  385. }
  386. return dirPath;
  387. }
  388. std::string CLewaimaiString::BuZifuLeft(std::string old, int num, const char zifu)
  389. {
  390. return std::string(num, zifu) + old;
  391. }
  392. std::string CLewaimaiString::GetQuweima(std::wstring input)
  393. {
  394. //先转换成GB2312,区位码都是相对于GB2312的
  395. std::string gb_hanzi = CLewaimaiString::UnicodeToGBK(input);
  396. std::string result = "";
  397. for (size_t i = 0; i < gb_hanzi.length() - 1; )
  398. {
  399. byte* cur = (byte*)(gb_hanzi.c_str() + i);
  400. if (*cur >= 0 && *cur <= 127)
  401. {
  402. //正常的asicc码,字符串或者数字
  403. int front = (short)(*cur - '\0');
  404. front -= 32;
  405. if (front < 10)
  406. {
  407. result += "030" + std::to_string(front);
  408. }
  409. else
  410. {
  411. result += "03" + std::to_string(front);
  412. }
  413. i++;
  414. }
  415. else
  416. {
  417. int front = (short)(cur[0] - '\0');//将字节数组的第一位转换成short类型,这里(short)code[0]也是可以的
  418. int back = (short)(cur[1] - '\0');//将字节数组的第二位转换成short类型
  419. std::string s_front = std::to_string(front - 160);
  420. if (front - 160 < 10)
  421. {
  422. //前面补0
  423. s_front = "0" + s_front;
  424. }
  425. std::string s_back = std::to_string(back - 160);
  426. if (back - 160 < 10)
  427. {
  428. //前面补0
  429. s_back = "0" + s_back;
  430. }
  431. result += s_front + s_back;
  432. i++;
  433. i++;
  434. }
  435. }
  436. return result;
  437. }
  438. std::string CLewaimaiString::GetBarcodeCheckCode(const std::string& barcode)
  439. {
  440. if (barcode.length() != 12 || !CLewaimaiString::is_only_number(barcode))
  441. {
  442. return "";
  443. }
  444. int sum = 0;
  445. for (size_t i = 0; i < barcode.length(); ++i)
  446. {
  447. int digit = barcode[i] - '0';
  448. sum += digit * (i % 2 == 0 ? 1 : 3);
  449. }
  450. return std::to_string((10 - sum % 10) % 10);
  451. }
  452. std::string CLewaimaiString::SqlZhuanyi(std::string old)
  453. {
  454. CLewaimaiString::string_replace(old, "'", "''");
  455. return old;
  456. }
  457. std::wstring CLewaimaiString::ShuziInputFormat(std::wstring old, std::wstring input)
  458. {
  459. if (old == L"0")
  460. {
  461. if (input == L".")
  462. {
  463. return old + input;
  464. }
  465. else if(input == L"0")
  466. {
  467. return L"0";
  468. }
  469. else
  470. {
  471. return input;
  472. }
  473. }
  474. int pos = old.find(L".");
  475. if (pos != old.npos)
  476. {
  477. //已经有一个.了
  478. if (input == L".")
  479. {
  480. return old;
  481. }
  482. if (old.length() - pos > 2)
  483. {
  484. //小数点后已经有2个数字了
  485. return old;
  486. }
  487. return old + input;
  488. }
  489. else
  490. {
  491. //还没有小数点
  492. return old + input;
  493. }
  494. }
  495. bool CLewaimaiString::is_only_number(std::string str)
  496. {
  497. for (size_t i = 0; i < str.size(); i++)
  498. {
  499. if ((str.at(i) > '9') || (str.at(i) < '0'))
  500. {
  501. return false;
  502. }
  503. }
  504. return true;
  505. }
  506. std::string CLewaimaiString::GenerateRandomStr(size_t len, bool useTimeSeed)
  507. {
  508. // 1. 定义字符集:大小写字母 + 数字(可自行增删)
  509. const std::string charset = "0123456789"
  510. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  511. "abcdefghijklmnopqrstuvwxyz";
  512. if (len == 0 || charset.empty())
  513. {
  514. return "";
  515. }
  516. // 2. 生成时间种子(关键:精确到微秒,不同时间种子一定不同)
  517. std::random_device rd; // 硬件随机数(辅助增强随机性)
  518. uint64_t timeSeed = 0;
  519. if (useTimeSeed)
  520. {
  521. // 获取当前系统时间戳(从1970年1月1日到现在的微秒数)
  522. auto now = std::chrono::system_clock::now().time_since_epoch();
  523. timeSeed = std::chrono::duration_cast<std::chrono::microseconds>(now).count();
  524. }
  525. // 3. 初始化随机数生成器(混合硬件随机数 + 时间种子)
  526. std::mt19937_64 rng;
  527. if (useTimeSeed)
  528. {
  529. rng.seed(rd() ^ timeSeed); // 时间+硬件双重种子
  530. }
  531. else
  532. {
  533. rng.seed(rd());
  534. }
  535. // 4. 均匀分布:随机取字符集里的字符
  536. std::uniform_int_distribution<> dist(0, (int)charset.size() - 1);
  537. // 5. 生成字符串
  538. std::string result;
  539. result.reserve(len); // 预分配内存,提升效率
  540. for (size_t i = 0; i < len; ++i)
  541. {
  542. result += charset[dist(rng)];
  543. }
  544. return result;
  545. }