/**
* ========================================================
* 北京五八信息技术有限公司技术中心开发一部
* 日 期:2011-5-10 下午01:59:00
* 作 者:张纪豪
* 版 本:1.0.0
* ========================================================
* 修订日期 修订人 描述
*
*/
package org.howsun.util;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
import org.howsun.log.Log;
import org.howsun.log.LogFactory;
/**
* 功能描述:IPv4工具
*
* @author howsun(howsun.zhang@google.com)
* @version 1.0.0
*/
public abstract class Ips {
private static final Log logger = LogFactory.getLog(Ips.class);
/**
* 从ip的字符串形式得到字节数组形式
* @param ip 字符串形式的ip
* @return 字节数组形式的ip
*/
public static byte[] getIpByteArrayFromString(String ip) {
byte[] ret = new byte[4];
StringTokenizer st = new StringTokenizer(ip, ".");
try {
ret[0] = (byte)(Integer.parseInt(st.nextToken()) & 0xFF);
ret[1] = (byte)(Integer.parseInt(st.nextToken()) & 0xFF);
ret[2] = (byte)(Integer.parseInt(st.nextToken()) & 0xFF);
ret[3] = (byte)(Integer.parseInt(st.nextToken()) & 0xFF);
} catch (Exception e) {
logger.warn("从ip的字符串形式得到字节数组形式报错", e);
}
return ret;
}
/**
* @param ip ip的字节数组形式
* @return 字符串形式的ip
*/
public static String getIpStringFromBytes(byte[] ip) {
return new StringBuilder()
.append(ip[0] & 0xFF).append('.')
.append(ip[1] & 0xFF).append('.')
.append(ip[2] & 0xFF).append('.')
.append(ip[3] & 0xFF)
.toString();
}
/**
* 整数转换成IP地址
* @param value
* @return
*/
public static String long2ip(long value){
StringBuffer ip = new StringBuffer();
ip.append(String.valueOf((value >>> 24))) .append("."); //直接右移24位
ip.append(String.valueOf((value & 0x00FFFFFF) >>> 16)).append("."); //将高8位置0,然后右移16位
ip.append(String.valueOf((value & 0x0000FFFF) >>> 8)) .append("."); //将高16位置0,然后右移8位
ip.append(String.valueOf((value & 0x000000FF))); //将高24位置0
return ip.toString();
}
/**
* ip地址转换成整数
* @param ip
* @return
*/
public static long ip2long(String ip){
long result = 0;
if(Strings.hasLength(ip)){
String section[] = ip.split("\\.");
if(section.length > 2){
for (int i = 0; i < section.length; i++) {
result += Long.parseLong(section[i]) << ((section.length - i - 1) * 8);
}
}
}
return result;
}
public static Set<String> IP_HEADERS = new HashSet<String>(Arrays.asList("x-forwarded-for", "x-real-ip", "proxy-client-ip", "wl-proxy-client-ip"));
/**
* 获取IP地址<br>
* 首先判断是不是测试IP地址,再判断是不是代理,最后才正常获取
*
* 2013-03-12:增加Nginx反向代理识别,不过Nginx服务端需要加上配置,代码如下:
* proxy_set_header Host $host;
* proxy_set_header X-real-ip $remote_addr;
* proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
*
* @param request
* @return
*/
public static long getIp(HttpServletRequest request) {
String ip = request.getParameter("ip");
if(!Strings.hasLength(ip)){
ip = request.getRemoteAddr();
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "127.0.0.1".equals(ip)) {//Nginx代理后IP为本机地址
Enumeration<?> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()){
String headerName = String.valueOf(headerNames.nextElement());
if(IP_HEADERS.contains(headerName.toLowerCase())){
ip = request.getHeader(headerName);
if(Strings.hasLengthBytrim(ip) && !"unknown".equalsIgnoreCase(ip)) {
break;
}
}
}
if(ip != null && ip.indexOf(",") > 0){
ip = ip.split(",")[0];
}
}
return ip2long(ip);
}
public static void main(String[] args) {
byte b[] = {(byte)127,(byte)0,(byte)0,(byte)1};
System.out.println(ip2long("127.0.0.1"));
System.out.println(long2ip(2130706433L));
System.out.println(getIpStringFromBytes(b));
System.out.println(ip2long(getIpStringFromBytes(b)));
}
}