public static boolean compareVersion(String version1, String version2) {
String[] versionArray1 = version1.split("\\.");
String[] versionArray2 = version2.split("\\.");
int idx = 0;
int minLength = Math.min(versionArray1.length, versionArray2.length);
int diff = 0;
while (idx < minLength && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0
&& (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {
++idx;
}
diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length;
return diff>0;
}
/**
* @author [email protected]
* 比较版本漏洞
* @version 1.0
* @date 2020/12/6 14:24
*/
public class VersionUtil {
public static void main(String[] args) {
//当前版本低于要求的版本则会返回true,表明有风险
String newVersion="<6.x,<5.1";
String currentVersion = "6.10";
System.out.println(compareVersions(newVersion,currentVersion));
}
public static String compareVersions(String newVersion,String currentVersion){
if(newVersion.split(",").length>0){
//分割逗号,处理多个值(2018.011.20040,<=2017.011.30080,<=2015.006.30418)
String[] newVersions = newVersion.split(",");
for (String temp :newVersions){
if (isStartWithNumber(temp)){
//如果是数字开头的话
if (temp.equals(currentVersion)){
//直接匹配版本是否相同,处理(15.6,12.4)这种情况
System.out.println("当前版本在此范围内,含有此漏洞1");
return currentVersion;
}
}
else {
//如果是<= 或者<这种情况
try{
if(temp.startsWith("<")){
//如果是<
String tempVersion = extractNumbers(temp);
if(compareVersion(tempVersion,currentVersion)){
//先提取出数字,再比较是否在数字范围里面,处理(2018.011.20040,<=2017.011.30080,<=2015.006.30418)
System.out.println("当前版本在此范围内,含有此漏洞2");
return currentVersion;
}
}
if (temp.startsWith("<=")||temp.startsWith("< =")){
//如果是<=
String tempVersion = extractNumbers(temp);
if (compareVersion(tempVersion,currentVersion)||tempVersion.equals(currentVersion)) {
System.out.println("当前版本在此范围内,含有此漏洞3");
return currentVersion;
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
else {
//处理没逗号的情况
if (isStartWithNumber(newVersion)){
//如果是数字开头的话
if (newVersion.equals(currentVersion)){
//直接匹配版本是否相同,处理(15.6,12.4)这种情况
System.out.println("当前版本在此范围内,含有此漏洞1");
return currentVersion;
}
}
else {
//如果是<= 或者<这种情况
try{
if(newVersion.startsWith("<")){
//如果是<
String tempVersion = extractNumbers(newVersion);
if(compareVersion(tempVersion,currentVersion)){
//先提取出数字,再比较是否在数字范围里面,处理(2018.011.20040,<=2017.011.30080,<=2015.006.30418)
System.out.println("当前版本在此范围内,含有此漏洞2");
return currentVersion;
}
}
if (newVersion.startsWith("<=")||newVersion.startsWith("< =")){
//如果是<=
String tempVersion = extractNumbers(newVersion);
if (compareVersion(tempVersion,currentVersion)||tempVersion.equals(currentVersion)) {
System.out.println("当前版本在此范围内,含有此漏洞3");
return currentVersion;
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
return null;//如果都没匹配上,表示没漏洞,返回空
}
/**
* 比较版本号的大小,前者大则返回一个正数(true),后者大返回一个负数(false),相等则返回0(false),如果是1.x 对比1.5这种,1.x大于带数字的版本,字母会认为是全匹配
*
* @param version1 ignore
* @param version2 ignore
* @return ignore
*/
public static boolean compareVersion(String version1, String version2) {
// 切割点 ".";
version1 = version1.replace("x","99999");
version1 = version1.replace("X","99999");
String[] versionArray1 = version1.split("\\.");
String[] versionArray2 = version2.split("\\.");
int idx = 0;
// 取最小长度值
int minLength = Math.min(versionArray1.length, versionArray2.length);
int diff = 0;
// 先比较长度 再比较字符
while (idx < minLength && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0
&& (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {
++idx;
}
// 如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大;
diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length;
return diff>0;
}
/**
* 提取出数字
* @param versionRange
* @return
*/
public static String extractNumbers(String versionRange){
Pattern patternEnd = Pattern.compile("\\d+\\S+");
Matcher matcherEnd = patternEnd.matcher(versionRange);
if (matcherEnd.find()){
return matcherEnd.group();
}
else
return null;
}
/**
* 判断是否为数字开头
* @param str
* @return
*/
public static boolean isStartWithNumber(String str) {
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str.charAt(0)+"");
if (!isNum.matches()) {
return false;
}
return true;
}
}