Skip to content

Instantly share code, notes, and snippets.

@johnroyer
Last active July 5, 2017 03:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnroyer/9f8ddfa1592d8c131d8e04407b8caf3e to your computer and use it in GitHub Desktop.
Save johnroyer/9f8ddfa1592d8c131d8e04407b8caf3e to your computer and use it in GitHub Desktop.
simple IPv4 checker (CIDR included)
<?php
declare(strict_types=1);
class IPv4
{
/**
* Check if input is a valid IPv4 address
*
* A valid IPv4 address is presents like `192.168.1.1`
*
* @param string $input
* @return bool true if address is valid, false if not
*/
public static function isIpAddress(string $input): bool
{
$res = preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $input);
if (1 !== $res) {
return false;
}
$class = explode('.', $input);
foreach ($class as $num) {
if ($num > 255) {
return false;
}
}
return true;
}
/**
* Check input is a valid CIDR expression
*
* CIDR is present as `196.168.0.0/16`
*
* @param string $input
* @return bool true if CIDR is valid, false if not
*/
public static function isCidr($input): bool
{
if (1 !== preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}?$/", $input)) {
return false;
}
// mask check
list($ip, $mask) = explode('/', $input);
if (32 < intval($mask)) {
return false;
}
// class number check
foreach (explode('.', $ip) as $num) {
if ($num > 255) {
return false;
}
}
return true;
}
/**
* Check input is a valid hostname
*
* A valid hostname can be reverse to an IP address
*
* @param string $input
* @return bool true if valid, false if not
*/
public static function isHostname($input): bool
{
$ip = gethostbyname($input);
if ($ip === $input) {
// 正解失敗,或是原本就是 IP address
return false;
}
if (!static::isIpAddress($ip)) {
// 正解出來的不是正常的 IP
return false;
}
return true;
}
}
<?php
require 'IPv4.php';
use PHPUnit\Framework\TestCase;
class IPv4Test extends TestCase
{
public function setUp()
{
}
public function tearDown()
{
}
/**
* @dataProvider ipAddressProvider
*/
public function testIpChecker($input, $expected)
{
$this->assertSame($expected, IPv4::isIpAddress($input));
}
public function ipAddressProvider()
{
return [
['127.0.0.1', true],
['192.168.2.255', true],
['172.16.200.1', true],
['10.0.0.1', true],
['8.8.8.8', true],
['192.168.1.300', false],
['10.0.0.1/24', false], // do not support CIDR
['www.hermes.com.tw', false], // IPv4 address only
];
}
/**
* @dataProvider cidrProvider
*/
public function testCidrChecker($input, $expected)
{
$this->assertSame($expected, IPv4::isCidr($input));
}
public function cidrProvider()
{
return [
['192.168.1.1/24', true],
['10.0.0.0/8', true],
['172.16.0.0/16', true],
['10.1.0.0/24', true],
['10.2.3.0/30', true],
['192.168.1.1', false], // CIDR only
['192.168.1.1/', false], // wrong format
['192.168.300.1/32', false], // 300 is invalid
['www.hermes.com.tw', false],
];
}
/**
* @dataProvider hostnameProvider
*/
public function testHostnameChecker($input, $expected)
{
$this->assertSame($expected, IPv4::isHostname($input));
}
public function hostnameProvider()
{
return [
['www.google.com', true],
['mail.google.com', true],
['php.net', true],
['www.netflix.com', true],
['this-is-not-domain', false],
['10.0.0.1', false],
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment