集册 Java实例教程 是IPv6文本地址

是IPv6文本地址

欢马劈雪     最近更新时间:2020-01-02 10:19:05

489
提示:您可在线编辑运行本教程的实例 - 运行实例,去试试!
是IPv6文本地址

/*

 * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.

 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.

 *

 * This code is free software; you can redistribute it and/or modify it

 * under the terms of the GNU General Public License version 2 only, as

 * published by the Free Software Foundation.  Oracle designates this

 * particular file as subject to the "Classpath" exception as provided

 * by Oracle in the LICENSE file that accompanied this code.

 *

 * This code is distributed in the hope that it will be useful, but WITHOUT

 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License

 * version 2 for more details (a copy is included in the LICENSE file that

 * accompanied this code).

 *

 * You should have received a copy of the GNU General Public License version

 * 2 along with this work; if not, write to the Free Software Foundation,

 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.

 *

 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA

 * or visit www.oracle.com if you need additional information or have any

 * questions.

 */

//package com.nowjava;


public class Main {//nowjava.com - 时代Java 提 供

    public static void main(String[] argv) throws Exception {

        String src = "nowjava.com";

        System.out.println(isIPv6LiteralAddress(src));

    }


    private static final int INADDR4SZ = 4;

    private static final int INADDR16SZ = 16;

    private static final int INT16SZ = 2;

    /**
     * 时 代      J a v a   公   众 号 - nowjava.com 提 供 
    **/

    /**

     * @param src a String representing an IPv6 address in textual format

     * @return a boolean indicating whether src is an IPv6 literal address

     */

    public static boolean isIPv6LiteralAddress(String src) {

        return textToNumericFormatV6(src) != null;

    }


    public static byte[] textToNumericFormatV6(String src) {

        // Shortest valid string is "::", hence at least 2 chars

        if (src.length() < 2) {

            return null;

        }


        int colonp;

        char ch;

        boolean saw_xdigit;

        int val;

        char[] srcb = src.toCharArray();

        byte[] dst = new byte[INADDR16SZ];


        int srcb_length = srcb.length;

        int pc = src.indexOf('%');

        if (pc == srcb_length - 1) {

            return null;

        }


        if (pc != -1) {

            srcb_length = pc;

        }


        colonp = -1;

        int i = 0, j = 0;

        /* Leading :: requires some special handling. */

        if (srcb[i] == ':')

            if (srcb[++i] != ':')

                return null;

        int curtok = i;

        saw_xdigit = false;

        val = 0;

        while (i < srcb_length) {

            ch = srcb[i++];

            int chval = Character.digit(ch, 16);

            if (chval != -1) {

                val <<= 4;

                val |= chval;

                if (val > 0xffff)

                    return null;

                saw_xdigit = true;

                continue;

            }

            if (ch == ':') {

                curtok = i;

                if (!saw_xdigit) {

                    if (colonp != -1)

                        return null;

                    colonp = j;

                    continue;

                } else if (i == srcb_length) {

                    return null;

                }

                if (j + INT16SZ > INADDR16SZ)

                    return null;

                dst[j++] = (byte) ((val >> 8) & 0xff);

                dst[j++] = (byte) (val & 0xff);

                saw_xdigit = false;

                val = 0;

                continue;

            }

            if (ch == '.' && ((j + INADDR4SZ) <= INADDR16SZ)) {

                String ia4 = src.substring(curtok, srcb_length);

                /* check this IPv4 address has 3 dots, ie. A.B.C.D */

                int dot_count = 0, index = 0;

                while ((index = ia4.indexOf('.', index)) != -1) {

                    dot_count++;

                    index++;

                }

                if (dot_count != 3) {

                    return null;

                }

                byte[] v4addr = textToNumericFormatV4(ia4);

                if (v4addr == null) {

                    return null;

                }

                for (int k = 0; k < INADDR4SZ; k++) {

                    dst[j++] = v4addr[k];

                }

                saw_xdigit = false;

                break; /* '\0' was seen by inet_pton4(). */

            }

            return null;

        }

        if (saw_xdigit) {

            if (j + INT16SZ > INADDR16SZ)

                return null;

            dst[j++] = (byte) ((val >> 8) & 0xff);

            dst[j++] = (byte) (val & 0xff);

        }


        if (colonp != -1) {

            int n = j - colonp;


            if (j == INADDR16SZ)

                return null;

            for (i = 1; i <= n; i++) {

                dst[INADDR16SZ - i] = dst[colonp + n - i];

                dst[colonp + n - i] = 0;

            }

            j = INADDR16SZ;

        }

        if (j != INADDR16SZ)

            return null;

        byte[] newdst = convertFromIPv4MappedAddress(dst);

        if (newdst != null) {

            return newdst;

        } else {

            return dst;

        }

    }


    @SuppressWarnings("fallthrough")

    public static byte[] textToNumericFormatV4(String src) {

        byte[] res = new byte[INADDR4SZ];


        long tmpValue = 0;

        int currByte = 0;

        boolean newOctet = true;


        int len = src.length();

        if (len == 0 || len > 15) {

            return null;

        }

        /*

         * When only one part is given, the value is stored directly in

         * the network address without any byte rearrangement.

         *

         * When a two part address is supplied, the last part is

         * interpreted as a 24-bit quantity and placed in the right

         * most three bytes of the network address. This makes the

         * two part address format convenient for specifying Class A

         * network addresses as net.host.

         *

         * When a three part address is specified, the last part is

         * interpreted as a 16-bit quantity and placed in the right

         * most two bytes of the network address. This makes the

         * three part address format convenient for specifying

         * Class B net- work addresses as 128.net.host.

         *

         * When four parts are specified, each is interpreted as a

         * byte of data and assigned, from left to right, to the

         * four bytes of an IPv4 address.

         *

         * We determine and parse the leading parts, if any, as single

         * byte values in one pass directly into the resulting byte[],

         * then the remainder is treated as a 8-to-32-bit entity and

         * translated into the remaining bytes in the array.

         */

        for (int i = 0; i < len; i++) {

            char c = src.charAt(i);

            if (c == '.') {

                if (newOctet || tmpValue < 0 || tmpValue > 0xff

                        || currByte == 3) {

                    return null;

                }

                res[currByte++] = (byte) (tmpValue & 0xff);

                tmpValue = 0;

                newOctet = true;

            } else {

                int digit = Character.digit(c, 10);

                if (digit < 0) {

                    return null;

                }

                tmpValue *= 10;

                tmpValue += digit;

                newOctet = false;

            }

        }

        if (newOctet || tmpValue < 0

                || tmpValue >= (1L << ((4 - currByte) * 8))) {

            return null;

        }

        switch (currByte) {

        case 0:

            res[0] = (byte) ((tmpValue >> 24) & 0xff);

        case 1:

            res[1] = (byte) ((tmpValue >> 16) &
展开阅读全文