Created
July 22, 2025 14:39
-
-
Save ronchaine/ca9a7af96a37fa690d55b1057e6bc7ce to your computer and use it in GitHub Desktop.
quick checking for valid hostname / ip address
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| constexpr bool is_digit(char32_t c) noexcept { | |
| return c >= '0' && c <= '9'; | |
| } | |
| constexpr bool is_alpha(char32_t c) noexcept { | |
| return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); | |
| } | |
| constexpr bool is_alphanum(char32_t c) noexcept { | |
| return is_digit(c) || is_alpha(c); | |
| } | |
| constexpr bool is_valid_ipv4_address(std::string_view in_str) noexcept { | |
| if (in_str.empty()) { | |
| return false; | |
| } | |
| uint16_t value = 0; | |
| uint8_t current_digit = 0; | |
| uint8_t block = 0; | |
| uint8_t result[4]; | |
| for (auto c : in_str) { | |
| if (block > 3) { | |
| return false; | |
| } | |
| else if (c == '.') { | |
| if (value > 255) { | |
| return false; | |
| } | |
| result[block] = static_cast<uint8_t>(value); | |
| value = 0; | |
| current_digit = 0; | |
| block++; | |
| continue; | |
| } | |
| else if (not is_digit(c)) { | |
| return false; | |
| } | |
| if (current_digit == 0) { | |
| value += (c - '0') * 100; | |
| } | |
| else if (current_digit == 1) { | |
| value += (c - '0') * 10; | |
| } | |
| else if (current_digit == 2) { | |
| value += (c - '0'); | |
| } | |
| else { | |
| return false; | |
| } | |
| if (value > 255) { | |
| return false; | |
| } | |
| current_digit++; | |
| } | |
| return true; | |
| } | |
| static_assert(not is_valid_ipv4_address("")); | |
| static_assert(is_valid_ipv4_address("127.0.0.1")); | |
| constexpr bool is_valid_hostname(std::string_view in_str) { | |
| if (in_str.empty()) | |
| return false; | |
| bool hyphen_allowed = false; | |
| bool period_allowed = false; | |
| char last_domainlabel_start = '\0'; | |
| char previous = '\0'; | |
| for (auto c : in_str) { | |
| if (is_alphanum(c)) { | |
| if ((previous == '.') || (previous == '\0')) | |
| last_domainlabel_start = c; | |
| previous = c; | |
| hyphen_allowed = true; | |
| period_allowed = true; | |
| continue; | |
| } | |
| else if ((c == '-') and hyphen_allowed) { | |
| previous = c; | |
| hyphen_allowed = false; | |
| period_allowed = false; | |
| continue; | |
| } | |
| else if ((c == '.') and period_allowed) { | |
| if (not is_alphanum(previous)) | |
| return false; | |
| previous = c; | |
| hyphen_allowed = false; | |
| period_allowed = false; | |
| continue; | |
| } | |
| return false; | |
| } | |
| // RFC2396 prevents last domain label from starting with a digit | |
| return is_alpha(last_domainlabel_start); | |
| } | |
| static_assert(is_valid_hostname("a.b.c.d")); | |
| static_assert(is_valid_hostname("24.55.21.b200")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment