         return String(bytes: bytes, encoding: .ascii)
     }
 }
+
+extension CharacterSet {
+    public static var hexCharacters: CharacterSet { return CharacterSet(charactersIn: "1234567890abcdefABCDEF") }
+}

    }

    func isAllDigits() -> Bool {
        let digits = CharacterSet.decimalDigits
        guard let _:Range = rangeOfCharacter(from: digits.inverted) else {
            return true
        }
        
        return false
    }

    func isAllHexDigits() -> Bool {
        let hexCharacters = CharacterSet(charactersIn: "1234567890abcdefABCDEF")
        guard let _:Range = rangeOfCharacter(from: hexCharacters.inverted) else {
            return true
        }


        return isLikeIPV4Address() || isLikeIPV6Address();
    }

    //exactly four set of integers, in the range 0...255, separated by periods
    func isLikeIPV4Address() -> Bool {
        //tokenize on period, omit empty components for quick exclusion
        let components = self.split(separator: ".", omittingEmptySubsequences: true)
        guard components.count == 4 else {
            return false
        }
        
        if let _ = components.first(where: {UInt8($0) == nil}) {
            return false
        }
        
        return true
    }

    //set of up to eight (16 bit) hex values in the range 0...65535 separated by colons
    // edge cases:
    //  components with leading zeros may have only a two digit hex value
    //  components with a zero value can be represented by a single digit hex value: 0
    //  runs of components with zero values can be coalesced into a single empty component
    //  there can be at most one coalesced component
    func isLikeIPV6Address() -> Bool {
        //tokenize on colon, keep empty components so we can test for multiples
        let components = self.split(separator: ":", omittingEmptySubsequences: false)
        guard components.count <= 8 else {
            return false
        }

        //test for multiple empty components
        let filtered = components.filter({!$0.isEmpty})
        guard components.count - filtered.count <= 1 else {
            return false
        }

        //test remaining components for valid hex values in the range 0...65535
        if let _ = filtered.first(where: {UInt16($0, radix: 16) == nil}) {
            return false
        }

