前段时间写一个EOS的合约,需求中提到用IP作主索引,以保证用户IP的唯一性,因此自己写了下IPv4和uint32_t类型之间的转换。规则其实很简单,就是每8位转换成一段,或者一段转换成8位:
#define IP_MARK "." //IP convert to uint uint32_t ipToInt(std::string &strIp) { if (strIp.size() > 15) return 0; //最大长度不超过15 uint32_t nRet = 0; std::string strTmp; std::size_t pos; for (int i = 0; i < 3; ++i) { pos = strIp.find(IP_MARK, 0); if (pos == std::string::npos && pos > 3) return 0; //找不到“.”或一段大于3个字符,意味着格式不符合 strTmp = strIp.substr(0, pos); strIp = strIp.substr(pos + 1); nRet += std::stoi(strTmp) << ((3 - i) * 8); } if (strIp.size() > 3) return 0; nRet += std::stoi(strIp); return nRet; } //uint convert to IP std::string intToIp(uint32_t num) { std::string strIP = ""; for (int i = 0; i < 4; ++i) { uint32_t tmp = (num >> ((3 - i) * 8)) & 0xFF; strIP += std::to_string(tmp); if (i < 3) { strIP += IP_MARK; } } return strIP; }
实际过程中,还进行了ip过滤,因为我们所需要的是公网ip,因此将非公网ip过滤掉:
//IP过滤:本地回环地址--127.0.0.1(2130706433)-127.255.255.254(2147483646); // 私网地址--10.0.0.0(167772160)-10.255.255.255(184549375)、192.168.0.0(3232235520)-192.168.255.255(3232301055)、172.16.0.0(2886729728)-172.16.255.255(2886795263); // 特殊地址--0.0.0.0(0)、169.254.0.1(2851995649)-169.254.255.255(2852061183) bool udfsproducer::isPublic(uint32_t num){ if (num == 0) return false; if (num >= 2130706433 && num <= 2147483646) return false; if (num >= 167772160 && num <= 184549375) return false; if (num >= 3232235520 && num <= 3232301055) return false; if (num >= 2886729728 && num <= 2886795263) return false; if (num >= 2851995649 && num <= 2852061183) return false; return true; }