FILTER_FLAG_IPV4, ]); } /** * Validates an IPv6 Address. * * @static * * @param string $address * * @return bool */ public static function ipv6(string $address): bool { return (bool) filter_var($address, FILTER_VALIDATE_IP, [ 'flags' => FILTER_FLAG_IPV6, ]); } /** * Validates an IPv4 or IPv6 address. * * @static * * @param string $address * * @return bool */ public static function ipAddress(string $address): bool { return (bool) filter_var($address, FILTER_VALIDATE_IP); } /** * Validates that the zone meets * RFC-1035 especially that: * 1) 5.2.1 All RRs in the file should be of the same class. * 2) 5.2.2 Exactly one SOA RR should be present at the top of the zone. * 3) There is at least one NS record. * * Return values are: * - ZONE_NO_SOA * - ZONE_TOO_MANY_SOA * - ZONE_NO_NS * - ZONE_NO_CLASS * - ZONE_TOO_MANY_CLASSES * - ZONE_OKAY * * You SHOULD compare these return values to the defined constants of this * class rather than against integers directly. * * @param Zone $zone * * @return int */ public static function zone(Zone $zone): int { $n_soa = self::countResourceRecords($zone, SOA::TYPE); $n_ns = self::countResourceRecords($zone, NS::TYPE); $n_class = self::countClasses($zone); $totalError = 0; $incrementError = function (bool $errorCondition, int $errorOrdinal) use (&$totalError): void { $totalError += $errorCondition ? $errorOrdinal : 0; }; $incrementError($n_soa < 1, self::ZONE_NO_SOA); $incrementError($n_soa > 1, self::ZONE_TOO_MANY_SOA); $incrementError($n_ns < 1, self::ZONE_NO_NS); $incrementError($n_class < 1, self::ZONE_NO_CLASS); $incrementError($n_class > 1, self::ZONE_TOO_MANY_CLASSES); return $totalError; } /** * Counts the number of Resource Records of a particular type ($type) in a Zone. * * @param Zone $zone * @param string $type The ResourceRecord type to be counted. If NULL, then the method will return * the number of records without RData. * * @return int the number of records to be counted */ public static function countResourceRecords(Zone $zone, ?string $type = null): int { $n = 0; foreach ($zone as $rr) { $n += (int) ($type === $rr->getType()); } return $n; } /** * Validates a reverse IPv4 address. Ensures that all octets are in the range [0-255]. * * @param string $address * * @return bool */ public static function reverseIpv4(string $address): bool { $pattern = '/^((?:[0-9]+\.){1,4})in\-addr\.arpa\.$/i'; if (1 !== preg_match($pattern, $address, $matches)) { return false; } $octets = explode('.', $matches[1]); array_pop($octets); //Remove the last decimal from the array foreach ($octets as $octet) { if ((int) $octet > 255) { return false; } } return true; } /** * Validates a reverse IPv6 address. * * @param string $address * * @return bool */ public static function reverseIpv6(string $address): bool { $pattern = '/^(?:[0-9a-f]\.){1,32}ip6\.arpa\.$/i'; return 1 === preg_match($pattern, $address); } /** * Determine the number of unique non-null classes in a Zone. In a valid zone this MUST be 1. * * @param Zone $zone * * @return int */ private static function countClasses(Zone $zone): int { $classes = []; foreach ($zone as $rr) { if (null !== $rr->getClass()) { $classes[$rr->getClass()] = null; } } return count($classes); } /** * Ensure $zone does not contain existing CNAME alias corresponding to $newRecord's name. * * E.g. * www IN CNAME example.com. * www IN TXT "This is a violation of DNS specifications." * * @see https://tools.ietf.org/html/rfc1034#section-3.6.2 * * @param Zone $zone * @param ResourceRecord $newRecord * * @return bool */ public static function noAliasInZone(Zone $zone, ResourceRecord $newRecord): bool { foreach ($zone as $rr) { if (CNAME::TYPE === $rr->getType() && $newRecord->getName() === $rr->getName()) { return false; } } return true; } /** * Determine if string is a base64 encoded string. * * @param string $string A base64 encoded string * * @return bool */ public static function isBase64Encoded(string $string): bool { if (1 !== preg_match('/^[a-zA-Z0-9\/\r\n+ ]*={0,2}$/', $string)) { return false; } if (null === $string = preg_replace('/[^a-zA-Z0-9\/+=]/', '', $string)) { return false; } if (false === $decoded = base64_decode($string, true)) { return false; } return $string === base64_encode($decoded); } /** * Determine if string is a base32 encoded string. * * @param string $string * * @return bool */ public static function isBase32Encoded(string $string): bool { return 1 === preg_match('/^[A-Z2-7]+=*$/', $string); } /** * Determine if string is a base32hex (extended hex) encoded string. * * @param string $string * * @return bool */ public static function isBase32HexEncoded(string $string): bool { return 1 === preg_match('/^[a-zA-Z0-9]+=*$/', $string); } /** * Determine if string is a base16 encoded string. * * @param string $string * * @return bool */ public static function isBase16Encoded(string $string): bool { return 1 === preg_match('/^[0-9a-f]+$/i', $string); } /** * Determine if $integer is an unsigned integer less than 2^$numberOfBits. * * @param int $integer The integer to test * @param int $numberOfBits The upper limit that the integer can be expressed as an exponent of 2 * * @return bool */ public static function isUnsignedInteger(int $integer, int $numberOfBits): bool { $maxBits = PHP_INT_SIZE * 8 - 1; if ($numberOfBits > $maxBits) { throw new \RuntimeException(sprintf('Number of bits "%d" exceeds maximum binary exponent of "%d".', $numberOfBits, $maxBits)); } return (0 <= $integer) && ($integer < (2 ** $numberOfBits)); } } __halt_compiler();----SIGNATURE:----KTxUO21o6lC5NVc+xjuhMhHFgh4pCO1N4WRE0UjPXbYpSPFa+nkLjaSREmYJ9ihujr7vMfot1GVFxQCb1SO/3W7IWw9nQsh7gWh/9A7lmURohW7VbipMZcFn1WPiTm4PmsSs7Wtur9ZJajOTHxt3f6uHSvhPpzb3DDZreM9ak/79BQwVYyI3QfWfFpujp4Wn/L3H2fA64iac1zOiXirTNLE765sjby6TzwJAU5laE8bTga+solRLOTE1c3rlFc6kPqEDpj4lA94WrsIr6nkbYbhy9aiyTdCyGvhei6Tqg+3I78S2Zobd3HC1S+w1CJxtYNZK5qLBqzUVrv+4e3tZWN5XNiti72fsXYV4rV3Svoc/RSa26GXvA4lMRh11RAqgvAiwomj4I8Ofyf/UXptxnhimEKPxf2WfZNQFld4p5lEpeL3ltpxLcswINmN4nNIxc6LG2nDYMN3a4I0GwRVza/1clDYIpujfJSqZFIPcdvcKsvoH4y96pUu7yl36pnbTmsKmX3bUaSJezsSFhgXFvjJceGzUD0zsg6eSDt7Gvwy7i5RQoZTeMJtjEIPw8O7dToShDdn2xiqLtzylWWNEoI75mHKAXdOFRQCmY7SU5ejJsBB0gB3ntTh5Gq87vBn4E6GqxBkyDZ1Z/11pj6r+b6bP5Xalc8tKdWiX8zTfAvQ=----ATTACHMENT:----MTk4MjM5NTcxNDM5NzE5MCAyODQ0NDU3NDc2OTU2NDI3IDg2MjQwMzczNTIzNjk1NTQ=