java:多网卡环境下获取MAC地址

NetworkUtil.java

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.primitives.Bytes;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class NetworkConfig
{
    public static enum Radix
    {
        /**
         * 二进制
         */
        BIN(2),
        /**
         * 十进制
         */
        DEC(10),
        /**
         * 十六进制
         */
        HEX(16);

        final int value;

        Radix(int radix)
        {
            this.value = radix;
        }
    }


    public static enum Filter implements Predicate<NetworkInterface>
    {
        /**
         * 过滤器: 所有网卡
         */
        ALL,
        /**
         * 过滤器: 在线设备,see also {@link NetworkInterface#isUp()}
         */
        UP,
        /**
         * 过滤器: 虚拟接口,see also {@link NetworkInterface#isVirtual()}
         */
        VIRTUAL,
        /**
         * 过滤器:LOOPBACK, see also {@link NetworkInterface#isLoopback()}
         */
        LOOPBACK,
        /**
         * 过滤器:物理网卡
         */
        PHYICAL_ONLY;

        @Override
        public boolean apply(NetworkInterface input)
        {
            if (null == input)
            {
                return false;
            }
            try
            {
                byte[] hardwareAddress;
                switch (this)
                {
                    case UP:
                        return input.isUp();
                    case VIRTUAL:
                        return input.isVirtual();
                    case LOOPBACK:
                        return input.isLoopback();
                    case PHYICAL_ONLY:
                        hardwareAddress = input.getHardwareAddress();
                        return null != hardwareAddress
                               && hardwareAddress.length > 0
                               && !input.isVirtual()
                               && !isVMMac(hardwareAddress);
                    case ALL:
                    default:
                        return true;
                }
            }
            catch (SocketException e)
            {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 根据过滤器{@code filters}指定的条件(AND)返回网卡设备对象
     *
     * @param filters
     * @return
     */
    @SafeVarargs
    @SuppressWarnings("unchecked")
    public static Set<NetworkInterface> getNICs(Predicate<NetworkInterface>... filters)
    {
        if (null == filters)
        {
            filters = new Predicate[] {Filter.ALL};
        }
        try
        {
            Iterator<NetworkInterface> filtered = Iterators.filter(
                Iterators.forEnumeration(NetworkInterface.getNetworkInterfaces()),
                Predicates.and(filters));
            return ImmutableSet.copyOf(filtered);
        }
        catch (SocketException e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * 返回所有物理网卡
     *
     * @return
     */
    public static Set<NetworkInterface> getPhysicalNICs()
    {
        return getNICs(Filter.PHYICAL_ONLY, Filter.UP);
    }

    /**
     * 将{@code byte[]} 转换为{@code radix}指定格式的字符串
     *
     * @param source
     * @param separator 分隔符
     * @param radix     进制基数
     * @return {@code source}为{@code null}时返回空字符串
     */
    public static final String format(byte[] source, String separator, final Radix radix)
    {
        if (null == source)
        {
            return "";
        }
        if (null == separator)
        {
            separator = "";
        }
        List<String> hex = Lists.transform(Bytes.asList(source), new Function<Byte, String>()
        {
            @Override
            public String apply(Byte input)
            {
                return String.copyValueOf(new char[] {
                    Character.forDigit((input & 240) >> 4, radix.value),
                    Character.forDigit(input & 15, radix.value)
                });
            }
        });
        return Joiner.on(separator).join(hex);
    }

    /**
     * MAC地址格式(16进制)格式化{@code source}指定的字节数组
     */
    public static final String formatMac(byte[] source, String separator)
    {
        return format(source, separator, Radix.HEX);
    }

    /**
     * 以IP地址格式(点分位)格式化{@code source}指定的字节数组<br>
     */
    public static final String formatIp(byte[] source)
    {
        return format(source, ".", Radix.DEC);
    }

    /**
     * 返回指定{@code address}绑定的网卡的物理地址(MAC)
     *
     * @param address
     * @return 指定的{@code address}没有绑定在任何网卡上返回{@code null}
     * @see {@link NetworkInterface#getByInetAddress(InetAddress)}
     * @see {@link NetworkInterface#getHardwareAddress()}
     */
    public static byte[] getMacAddress(InetAddress address)
    {
        try
        {
            NetworkInterface nic = NetworkInterface.getByInetAddress(address);
            return null == nic ? null : nic.getHardwareAddress();
        }
        catch (SocketException e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @param nic       网卡对象
     * @param separator 格式化分隔符
     * @return 表示MAC地址的字符串
     */
    public static String getMacAddress(NetworkInterface nic, String separator)
    {
        try
        {
            return format(nic.getHardwareAddress(), separator, Radix.HEX);
        }
        catch (SocketException e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * 参见 {@link #getMacAddress(InetAddress)}
     *
     * @param address
     * @param separator 格式化分隔符
     * @return 表示MAC地址的字符串
     */
    public static String getMacAddress(InetAddress address, String separator)
    {
        return format(getMacAddress(address), separator, Radix.HEX);
    }

    private static byte invalidMacs[][] = {
        {0x00, 0x05, 0x69},             // VMWare
        {0x00, 0x1C, 0x14},             // VMWare
        {0x00, 0x0C, 0x29},             // VMWare
        {0x00, 0x50, 0x56},             // VMWare
        {0x08, 0x00, 0x27},             // Virtualbox
        {0x0A, 0x00, 0x27},             // Virtualbox
        {0x00, 0x03, (byte)0xFF},       // Virtual-PC
        {0x00, 0x15, 0x5D}              // Hyper-V
    };

    private static boolean isVMMac(byte[] mac)
    {
        if (null == mac)
        {
            return false;
        }

        for (byte[] invalid : invalidMacs)
        {
            if (invalid[0] == mac[0] && invalid[1] == mac[1] && invalid[2] == mac[2])
            {
                return true;
            }
        }

        return false;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值