ip2long("012.012.012.012") возвращает false в Linux
Предположим, что в представлении адреса IPv4 есть начальные нули, например
012.012.012.012
.
Чтобы подавить начальные нули, я просто пишу следующий код, и на моем Mac он работает так, как я и ожидал:
% php -r 'var_dump(long2ip(ip2long("012.012.012.012")));'
Command line code:1:
string(11) "12.12.12.12"
% php --version
PHP 7.3.25 (cli) (built: Dec 25 2020 22:03:38) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.25, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.25, Copyright (c) 1999-2018, by Zend Technologies
with Xdebug v3.0.1, Copyright (c) 2002-2020, by Derick Rethans
Но этот простой фрагмент кода не работает на CentOS 7, похоже
ip2long("012.012.012.012")
возвращается
false
ценность:
$ php -r 'var_dump(long2ip(ip2long("012.012.012.012")));'
string(7) "0.0.0.0"
$ php --version
PHP 7.3.25 (cli) (built: Nov 24 2020 11:10:55) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.25, Copyright (c) 1998-2018 Zend Technologies
$ cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)
Обе версии PHP идентичны, и я ожидаю, что они будут возвращать одинаковые значения. Я также прочитал документы ip2long и попытался найти, есть ли какие-либо специальные параметры/конфигурации для этого поведения, но безуспешно.
Может ли кто-нибудь вести меня в правильном направлении? Чем они отличаются? А что мне делать?
1 ответ
Хорошо, я нашел виновника. Различная реализация
inet_pton(3)
между LLVM и GCC ведет такое поведение, как прокомментировал Русс-сан . Был баг-репорт о точно такой же проблеме 6 лет назад. Кажется, PHP v5.2.10 начал использовать
inet_pton
вместо
inet_addr
согласно , поэтому этому патчуболее старые версии PHP обрабатывают каждый фрагмент как восьмеричный.
тест.с
#include <stdio.h>
#include <arpa/inet.h>
#define INADDR "012.012.012.012"
int main() {
struct in_addr inaddr;
if (inet_pton(AF_INET, INADDR, &inaddr) == 0) {
printf("Invalid: %s\n", INADDR);
}
else {
printf("Valid: %s\n", INADDR);
}
return 0;
}
- Мак
% cc test.cc && ./a.out
Valid: 012.012.012.012
- линукс
$ cc test.cc && ./a.out
Invalid: 012.012.012.012
я отказался от использования
ip2long
/
long2ip
встроенные функции и теперь пытаюсь использовать https://github.com/mlocati/ip-lib
>>> \IPLib\Address\IPv4::fromString("1.2.3.12")->toString(true);
=> "001.002.003.012"
>>> \IPLib\Address\IPv4::fromString("001.002.003.012")->toString();
=> "1.2.3.12"
Пока никаких проблем.