diff options
| author | yinjiangyi <[email protected]> | 2020-11-15 13:15:04 +0800 |
|---|---|---|
| committer | yinjiangyi <[email protected]> | 2020-11-15 13:15:04 +0800 |
| commit | 5f7c6af5b61657f01b16fdb6c8a7c993cd30e8b7 (patch) | |
| tree | 38867c0dfea4b4e27bcacb6b289b5ba74bf7790b | |
| parent | 5b73080eb2a4a84d1ff867a3da9fbdf780a36369 (diff) | |
commit v2
19 files changed, 1055 insertions, 0 deletions
@@ -1,2 +1,39 @@ # UaAnalyser +根据user-agent分析ip对应的终端个数情况及相关信息 + +## Input +``` +String inputString = "69765" + "\t" + // userId + "192.168.50.13" + "\t" + // ip + "1765433230" + "\t" + // timeStamp + "'Dalvik/1.6.0 (Linux; U; Android 4.0.3; LG-E612f Build/IML74K)':4, " + + "'Dalvik/2.1.0 (Linux; U; Android 10; TNYAL00 Build/HUAWEITNY-AL00)':4" + + "'Mozilla/5.0 (iPhone; CPU iPhone OS 11_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15G77 === iOS/11.4.1 Model/iPhone10,1 BundleID/com.xunmeng.pinduoduo AppVersion/5.32.0 AppBuild/2009212125 pversion/1221 cURL/7.48.0':5" + + "'com.apple.trustd/1.0':1" + + "'server-bag [iPhone OS,13.6.1,17G80,iPhone10,2]':1" + + "'Microsoft-CryptoAPI/10.0':1" + + "'Mozilla/5.0 (Linux; Android 10; SM-G9600) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.110 Mobile Safari/537.36':10" + + "'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36':1"; // uaCntInfo +``` + +### Output +``` +// 相关字段: +// osCnt, browserCnt, deviceCnt, terminalCnt, terminalCatCnt, +// osList, browserList, deviceList, terminalList, terminalCatList +userInfo.getTerminalList(); // 获取terminalList字段值 +``` +* ``osCnt`` -操作系统数 +* ``browserCnt``-浏览器数 +* ``deviceCnt``-设备名数(如 "LG E612F") +* ``terminalCnt``-终端三元组标识数(os/browser/device) +* ``terminalCatCnt``-终端类别数(类别包括windows, apple, android三种) + + +## Usage + +``` +UaAnalyser uaAnalyser = new UaAnalyserImpl(); +UserInfo userInfo = uaAnalyser.getUserinfo(inputString); +``` @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.example</groupId> + <artifactId>UaAnalyserV2</artifactId> + <version>1.0-SNAPSHOT</version> + + <properties> + <maven.compiler.source>15</maven.compiler.source> + <maven.compiler.target>15</maven.compiler.target> + </properties> + + <dependencies> + <dependency> + <groupId>org.mariadb.jdbc</groupId> + <artifactId>mariadb-java-client</artifactId> + <version>2.6.2</version> + </dependency> + <dependency> + <groupId>ru.yandex.clickhouse</groupId> + <artifactId>clickhouse-jdbc</artifactId> + <version>0.2.4</version> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>2.6</version> + </dependency> + <!-- log4j support --> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>1.2.17</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + <version>1.6.6</version> + </dependency> + + + </dependencies> + +</project>
\ No newline at end of file diff --git a/src/main/java/com/example/ua/analyser/UaAnalyser.java b/src/main/java/com/example/ua/analyser/UaAnalyser.java new file mode 100644 index 0000000..df06447 --- /dev/null +++ b/src/main/java/com/example/ua/analyser/UaAnalyser.java @@ -0,0 +1,17 @@ +package com.example.ua.analyser; + +import com.example.ua.analyser.enums.UserInfo; + +/** + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public interface UaAnalyser { + /** + * 接口函数 + * @param inputString 输入用户信息 + * @return 分析结果-UserInfo类 + */ + public UserInfo getUserinfo(String inputString); +} diff --git a/src/main/java/com/example/ua/analyser/enums/RegexFeatureEnum.java b/src/main/java/com/example/ua/analyser/enums/RegexFeatureEnum.java new file mode 100644 index 0000000..209664f --- /dev/null +++ b/src/main/java/com/example/ua/analyser/enums/RegexFeatureEnum.java @@ -0,0 +1,42 @@ +package com.example.ua.analyser.enums; + +/** + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public enum RegexFeatureEnum { + /* 终端类别名 */ + TERMINAL_CAT_APPLE("apple", "终端类型名"), + TERMINAL_CAT_WINDOWS("windows", "终端类型名"), + TERMINAL_CAT_ANDROID("android", "终端类型名"), + + /* 终端类别字符串匹配特征 */ + TERMINAL_CAT_APPLE_FEATURE("com.apple.trustd", "终端类型特征字符串"), + TERMINAL_CAT_WINDOWS_FEATURE("Microsoft-CryptoAPI", "终端类型特征字符串"), + TERMINAL_CAT_ANDROID_FEATURE("Dalvik", "终端类型特征字符串"); + + private String code; + private String desc; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + private RegexFeatureEnum(String code, String desc){ + this.code = code; + this.desc = desc; + } +} diff --git a/src/main/java/com/example/ua/analyser/enums/StandardUaList.java b/src/main/java/com/example/ua/analyser/enums/StandardUaList.java new file mode 100644 index 0000000..95f43c0 --- /dev/null +++ b/src/main/java/com/example/ua/analyser/enums/StandardUaList.java @@ -0,0 +1,38 @@ +package com.example.ua.analyser.enums; + +import java.util.Arrays; +import java.util.List; + +/** + * windows真实浏览器ua + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public class StandardUaList { + + public List<String> getUaList() { + return uaList; + } + + private List<String> uaList = Arrays.asList( + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.3", + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4209.400", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36 Edg/85.0.564.51", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Win64; x64; Trident/7.0; .NET4.0C; .NET4.0E; McAfee)", + "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4209.400" + ); +} diff --git a/src/main/java/com/example/ua/analyser/enums/UserInfo.java b/src/main/java/com/example/ua/analyser/enums/UserInfo.java new file mode 100644 index 0000000..b56f3bf --- /dev/null +++ b/src/main/java/com/example/ua/analyser/enums/UserInfo.java @@ -0,0 +1,175 @@ +package com.example.ua.analyser.enums; + +import java.util.ArrayList; +import java.util.List; + +/** + * 用户信息结构 + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public class UserInfo { + /** + * input info + */ + private String userId; + private String ip; + private String timeStamp; + private String uaCntInfo; + private List<String> uaList = new ArrayList<>(); + + /** + * analyse result info + */ + private Integer osCnt; + private Integer browserCnt; + private Integer deviceCnt; + private Integer terminalCnt; + private Integer terminalCatCnt; + + private List<String> osList = new ArrayList<>(); + private List<String> browserList = new ArrayList<>(); + private List<String> deviceList = new ArrayList<>(); + private List<String> terminalCatList = new ArrayList<>(); + private List<List<String>> terminalList = new ArrayList<>(); + + public void update(){ + for (List<String> terminal : terminalList){ + if ((terminal.get(0) != null) && !(osList.contains(terminal.get(0)))){ + osList.add(terminal.get(0)); + } + if ((terminal.get(1) != null) && !(browserList.contains(terminal.get(1)))){ + browserList.add(terminal.get(1)); + } + if ((terminal.get(2) != null) && !(deviceList.contains(terminal.get(2)))){ + deviceList.add(terminal.get(2)); + } + } + osCnt = osList.size(); + browserCnt = browserList.size(); + deviceCnt = deviceList.size(); + terminalCnt = terminalList.size(); + terminalCatCnt = terminalCatList.size(); + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getTimeStamp() { + return timeStamp; + } + + public List<String> getUaList() { + return uaList; + } + + public void setUaList(List<String> uaList) { + this.uaList = uaList; + } + + public void setTimeStamp(String timeStamp) { + this.timeStamp = timeStamp; + } + + public String getUaCntInfo() { + return uaCntInfo; + } + + public void setUaCntInfo(String uaCntInfo) { + this.uaCntInfo = uaCntInfo; + } + + public Integer getOsCnt() { + return osCnt; + } + + public void setOsCnt(Integer osCnt) { + this.osCnt = osCnt; + } + + public Integer getBrowserCnt() { + return browserCnt; + } + + public void setBrowserCnt(Integer browserCnt) { + this.browserCnt = browserCnt; + } + + public Integer getDeviceCnt() { + return deviceCnt; + } + + public void setDeviceCnt(Integer deviceCnt) { + this.deviceCnt = deviceCnt; + } + + public Integer getTerminalCnt() { + return terminalCnt; + } + + public void setTerminalCnt(Integer terminalCnt) { + this.terminalCnt = terminalCnt; + } + + public Integer getTerminalCatCnt() { + return terminalCatCnt; + } + + public void setTerminalCatCnt(Integer terminalCatCnt) { + this.terminalCatCnt = terminalCatCnt; + } + + public List<String> getOsList() { + return osList; + } + + public void setOsList(List<String> osList) { + this.osList = osList; + } + + public List<String> getBrowserList() { + return browserList; + } + + public void setBrowserList(List<String> browserList) { + this.browserList = browserList; + } + + public List<String> getDeviceList() { + return deviceList; + } + + public void setDeviceList(List<String> deviceList) { + this.deviceList = deviceList; + } + + public List<List<String>> getTerminalList() { + return terminalList; + } + + public void setTerminalList(List<List<String>> terminalList) { + this.terminalList = terminalList; + } + + public List<String> getTerminalCatList() { + return terminalCatList; + } + + public void setTerminalCatList(List<String> terminalCatList) { + this.terminalCatList = terminalCatList; + } +} diff --git a/src/main/java/com/example/ua/analyser/impl/AndroidAnalyser.java b/src/main/java/com/example/ua/analyser/impl/AndroidAnalyser.java new file mode 100644 index 0000000..5e8f6a7 --- /dev/null +++ b/src/main/java/com/example/ua/analyser/impl/AndroidAnalyser.java @@ -0,0 +1,101 @@ +package com.example.ua.analyser.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.example.ua.analyser.enums.RegexFeatureEnum; +import com.example.ua.analyser.enums.UserInfo; +import com.example.ua.dao.QueryMariaDb; +import com.example.ua.dao.impl.QueryMariaDbImpl; +import org.mariadb.jdbc.MariaDbStatement; + +/** + * android类设备分析 + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public class AndroidAnalyser { + private UserInfo userInfo; + private MariaDbStatement connStatement; + private QueryMariaDb queryMariaDb = new QueryMariaDbImpl(); + + public AndroidAnalyser(MariaDbStatement connStatement, UserInfo userInfo){ + this.userInfo = userInfo; + this.connStatement = connStatement; + } + + public UserInfo getTriples(){ + List<String> tripleInDatabase; + List<String> tripleInRegex; + List<List<String>> tripleList = this.userInfo.getTerminalList(); + + //筛选androidUA + List<String> uaList = selectAndroidUa(this.userInfo.getUaList()); + if (uaList.size()==0){ + return null; + } + + for (String ua : uaList) { + tripleInDatabase = queryMariaDb.getTriple(this.connStatement, ua); + if (tripleInDatabase.size() > 0) { + if (!(tripleList.contains(tripleInDatabase))){ + tripleList.add(tripleInDatabase); + } + } else { //不进行重复解析 + tripleInRegex = parseAndroidUa(ua); + if ((tripleInRegex != null) && !(tripleList.contains(tripleInRegex))){ + tripleList.add(tripleInRegex); + } + } + } + this.userInfo.setTerminalList(tripleList); + this.userInfo.update(); + + return this.userInfo; + } + + private List<String> selectAndroidUa(List<String> uaList){ + List<String>selectedUaList = new ArrayList<>(); + + Pattern android = Pattern.compile(RegexFeatureEnum.TERMINAL_CAT_ANDROID_FEATURE.getCode()); + + for (String ua : uaList) { + if (android.matcher(ua).find()){ + selectedUaList.add(ua); + } + } + return selectedUaList; + } + + private List<String> parseAndroidUa(String ua){ + List<String> androidTerminal = Arrays.asList(new String[3]); + String dePattern = "; [a-zA-Z0-9\\s]+/"; + String versionPattern = "; U; [a-zA-Z0-9\\s\\.]+;"; + Pattern de = Pattern.compile(dePattern); + Pattern version = Pattern.compile(versionPattern); + Matcher matcher1 = de.matcher(ua); + Matcher matcher2 = version.matcher(ua); + + if (matcher1.find() && matcher2.find()) { + // os + String tmp = matcher2.group(0); + androidTerminal.set(0, tmp.substring(5, tmp.length()-1)); + // TODO browser + androidTerminal.set(1, null); + // device + tmp = matcher1.group(0); + androidTerminal.set(2, tmp.substring(2, tmp.length() - 1)); + } else { + return null; + } + return androidTerminal; + } + + + + +} diff --git a/src/main/java/com/example/ua/analyser/impl/AppleAnalyser.java b/src/main/java/com/example/ua/analyser/impl/AppleAnalyser.java new file mode 100644 index 0000000..1e4f9a2 --- /dev/null +++ b/src/main/java/com/example/ua/analyser/impl/AppleAnalyser.java @@ -0,0 +1,129 @@ +package com.example.ua.analyser.impl; + +import com.example.ua.analyser.enums.UserInfo; +import com.example.ua.dao.QueryMariaDb; +import com.example.ua.dao.impl.QueryMariaDbImpl; +import org.mariadb.jdbc.MariaDbStatement; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * apple类设备分析 + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public class AppleAnalyser { + private UserInfo userInfo; + private MariaDbStatement connStatement; + private QueryMariaDb queryMariaDb = new QueryMariaDbImpl(); + + public AppleAnalyser(MariaDbStatement connStatement, UserInfo userInfo){ + this.userInfo = userInfo; + this.connStatement = connStatement; + } + + public UserInfo getTriples(){ + List<String> tripleInDatabase; + List<String> tripleInRegex; + List<List<String>> tripleList = this.userInfo.getTerminalList(); + + //筛选Apple Ua + List<String> uaList = selectAppleUa(this.userInfo.getUaList()); + if (uaList.size()==0){ + return null; + } + + for (String ua : uaList) { + tripleInDatabase = queryMariaDb.getTriple(this.connStatement, ua); + if ((tripleInDatabase.size() > 0)) { + if (!(tripleList.contains(tripleInDatabase))) { + tripleList.add(tripleInDatabase); + } + } else { //不进行重复解析 + tripleInRegex = parseAppleUa(ua); + if ((tripleInRegex != null) && !(tripleList.contains(tripleInRegex))) { + tripleList.add(tripleInRegex); + } + } + } + this.userInfo.setTerminalList(tripleList); + this.userInfo.update(); + + return this.userInfo; + } + + public List<String> parseAppleUa(String ua) { + List<String> appleTerminal = Arrays.asList(new String[3]); + + String macPattern = "Mozilla.*Mac OS"; + String ipadPattern = "server-bag .*iPad"; + String iphoneString = "server-bag .*iPhone"; + Pattern mac = Pattern.compile(macPattern); + Pattern ipad = Pattern.compile(ipadPattern); + Pattern iphone1 = Pattern.compile(ipadPattern); + + if (mac.matcher(ua).find()) { + Pattern mozilla = Pattern.compile("\\(.*;"); + Pattern version = Pattern.compile(";.*\\)"); + Pattern macos = Pattern.compile("Mac OS X\\s.*\\)\\s"); + Matcher matcher1 = mozilla.matcher(ua); + Matcher matcher2 = version.matcher(ua); + + if (matcher1.find() && matcher2.find()) { + String tmp = matcher2.group(0); + Matcher matcher3 = macos.matcher(tmp); + if(matcher3.find()){ + String macversion = Arrays.asList(matcher3.group(0).split("\\)")).get(0).trim().replace("_","."); + appleTerminal.set(0, macversion); + appleTerminal.set(2, "Apple Mac"); + } + } + } else if (ipad.matcher(ua).find()) { + Pattern iPad = Pattern.compile("iPad.*]"); + Matcher matcher = iPad.matcher(ua); + if (matcher.find()) { + String tmp = matcher.group(); + appleTerminal.set(0, "iOS " + tmp.replace(',', '.').substring(4, tmp.length() - 1)); + appleTerminal.set(2, "Apple iPad"); + } + } + else if (iphone1.matcher(ua).find()) { + appleTerminal.set(0, "iOS"); + appleTerminal.set(2, "Apple iPhone"); + } + + if (Collections.frequency(appleTerminal, null) == 3) { + return null; + } + return appleTerminal; + } + + private List<String> selectAppleUa(List<String> uaList){ + List<String>selectedUaList = new ArrayList<>(); + + Pattern pattern1 = Pattern.compile("Mozilla.*Mac OS X\\s"); + Pattern pattern2 = Pattern.compile("server-bag .*iPad"); + Pattern pattern3 = Pattern.compile("server-bag .*iPhone"); + + for (int i = 0; i < uaList.size(); i++) { + String ua = uaList.get(i); + if (pattern1.matcher(ua).find() || pattern2.matcher(ua).find() || pattern3.matcher(ua).find()) { + selectedUaList.add(ua); + } + } + return selectedUaList; + } + + + + + + +} diff --git a/src/main/java/com/example/ua/analyser/impl/TerminalClassify.java b/src/main/java/com/example/ua/analyser/impl/TerminalClassify.java new file mode 100644 index 0000000..83c1e94 --- /dev/null +++ b/src/main/java/com/example/ua/analyser/impl/TerminalClassify.java @@ -0,0 +1,57 @@ +package com.example.ua.analyser.impl; + +import com.example.ua.analyser.enums.UserInfo; +import com.example.ua.analyser.enums.RegexFeatureEnum; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * get possible categories of terminal + */ +public class TerminalClassify { + + public static void checkSys(UserInfo userInfo){ + List<String> uaList = userInfo.getUaList(); + List<String> catList = userInfo.getTerminalCatList(); + + Pattern apple = Pattern.compile(RegexFeatureEnum.TERMINAL_CAT_APPLE_FEATURE.getCode()); + Pattern android = Pattern.compile(RegexFeatureEnum.TERMINAL_CAT_ANDROID_FEATURE.getCode()); + Pattern win = Pattern.compile(RegexFeatureEnum.TERMINAL_CAT_WINDOWS_FEATURE.getCode()); + + Map<String, Integer> catCnt = new HashMap<>(); + catCnt.put(RegexFeatureEnum.TERMINAL_CAT_APPLE.getCode(), 0); + catCnt.put(RegexFeatureEnum.TERMINAL_CAT_ANDROID.getCode(), 0); + catCnt.put(RegexFeatureEnum.TERMINAL_CAT_WINDOWS.getCode(), 0); + + for (String s : uaList) { + if (apple.matcher(s).find()) { + catCnt.put(RegexFeatureEnum.TERMINAL_CAT_APPLE.getCode(), + catCnt.get(RegexFeatureEnum.TERMINAL_CAT_APPLE.getCode()) + 1); + continue; + } + if (android.matcher(s).find()) { + catCnt.put(RegexFeatureEnum.TERMINAL_CAT_ANDROID.getCode(), + catCnt.get(RegexFeatureEnum.TERMINAL_CAT_ANDROID.getCode()) + 1); + continue; + } + if (win.matcher(s).find()) { + catCnt.put(RegexFeatureEnum.TERMINAL_CAT_WINDOWS.getCode(), + catCnt.get(RegexFeatureEnum.TERMINAL_CAT_WINDOWS.getCode()) + 1); + } + } + + if (catCnt.get(RegexFeatureEnum.TERMINAL_CAT_WINDOWS.getCode())!=0) + catList.add(RegexFeatureEnum.TERMINAL_CAT_WINDOWS.getCode()); + if (catCnt.get(RegexFeatureEnum.TERMINAL_CAT_ANDROID.getCode())!=0) + catList.add(RegexFeatureEnum.TERMINAL_CAT_ANDROID.getCode()); + if (catCnt.get(RegexFeatureEnum.TERMINAL_CAT_APPLE.getCode())!=0) + catList.add(RegexFeatureEnum.TERMINAL_CAT_APPLE.getCode()); + + userInfo.setTerminalCatList(catList); + } +} + + diff --git a/src/main/java/com/example/ua/analyser/impl/UaAnalyserImpl.java b/src/main/java/com/example/ua/analyser/impl/UaAnalyserImpl.java new file mode 100644 index 0000000..50c9131 --- /dev/null +++ b/src/main/java/com/example/ua/analyser/impl/UaAnalyserImpl.java @@ -0,0 +1,77 @@ +package com.example.ua.analyser.impl; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.example.ua.analyser.UaAnalyser; +import com.example.ua.analyser.enums.UserInfo; +import com.example.ua.utils.MariaDBConnect; +import com.example.ua.analyser.enums.RegexFeatureEnum; + +import org.mariadb.jdbc.MariaDbStatement; +//import org.slf4j.Logger; +import org.apache.log4j.Logger; + +public class UaAnalyserImpl implements UaAnalyser { + final Logger LOG = Logger.getLogger(UaAnalyser.class); + MariaDbStatement connStatement = MariaDBConnect.getMariaDB(); + + @Override + public UserInfo getUserinfo(String inputString){ + UserInfo userInfo = parseInfo(inputString); + List<List<String>> terminalList = userInfo.getTerminalList(); + + // get terminalCatInfo in userInfo + TerminalClassify.checkSys(userInfo); + + //android + if (userInfo.getTerminalCatList().contains(RegexFeatureEnum.TERMINAL_CAT_ANDROID.getCode())){ + AndroidAnalyser androidAnalyser = new AndroidAnalyser(connStatement, userInfo); + userInfo = androidAnalyser.getTriples(); + } + //windows + if (userInfo.getTerminalCatList().contains(RegexFeatureEnum.TERMINAL_CAT_WINDOWS.getCode())){ + WindowsAnalyser windowsAnalyser = new WindowsAnalyser(connStatement, userInfo); + userInfo = windowsAnalyser.getTriples(); + } + //apple + if (userInfo.getTerminalCatList().contains(RegexFeatureEnum.TERMINAL_CAT_WINDOWS.getCode())){ + AppleAnalyser appleAnalyser = new AppleAnalyser(connStatement, userInfo); + userInfo = appleAnalyser.getTriples(); + } + +// userInfo.setTerminalList(terminalList); + userInfo.update(); + return userInfo; + } + + public UserInfo parseInfo(String inputString){ + UserInfo userInfo = new UserInfo(); + List<String> uaList = userInfo.getUaList(); + + String[] info = inputString.split("\t"); + try{ + userInfo.setUserId(info[0]); + userInfo.setIp(info[1]); + userInfo.setTimeStamp(info[2]); + userInfo.setUaCntInfo(info[3]); + } catch (ArrayIndexOutOfBoundsException e) { + LOG.error("Input Format Error: " + inputString); + userInfo.update(); + return userInfo; + } + + Pattern pattern = Pattern.compile("\\'(.*?)\\'"); + Matcher matcher = pattern.matcher(userInfo.getUaCntInfo()); + while (matcher.find()) { + String tmp = matcher.group(0).replace("\'", ""); + uaList.add(tmp); + } + userInfo.setUaList(uaList); + + userInfo.update(); + return userInfo; + } + +} diff --git a/src/main/java/com/example/ua/analyser/impl/WindowsAnalyser.java b/src/main/java/com/example/ua/analyser/impl/WindowsAnalyser.java new file mode 100644 index 0000000..adafc43 --- /dev/null +++ b/src/main/java/com/example/ua/analyser/impl/WindowsAnalyser.java @@ -0,0 +1,73 @@ +package com.example.ua.analyser.impl; + +import com.example.ua.analyser.enums.StandardUaList; +import com.example.ua.analyser.enums.UserInfo; +import com.example.ua.dao.QueryMariaDb; +import com.example.ua.dao.impl.QueryMariaDbImpl; +import org.mariadb.jdbc.MariaDbStatement; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import org.apache.log4j.Logger; + + +/** + * windows类设备分析 + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public class WindowsAnalyser { + private static final Logger LOG = Logger.getLogger(WindowsAnalyser.class); + private UserInfo userInfo; + private MariaDbStatement connStatement; + private QueryMariaDb queryMariaDb = new QueryMariaDbImpl(); + + public WindowsAnalyser(MariaDbStatement connStatement, UserInfo userInfo) { + this.userInfo = userInfo; + this.connStatement = connStatement; + } + + public UserInfo getTriples() { + List<String> tripleInDatabase; + List<List<String>> tripleList = this.userInfo.getTerminalList(); + + // 筛选真实浏览器ua + List<String> uaList = selectStandardUa(this.userInfo.getUaList()); + if (uaList.size() == 0) { + return null; + } + + // 解析库解析 + for (String ua : uaList) { + tripleInDatabase = queryMariaDb.getTriple(this.connStatement, ua); + if ((tripleInDatabase.size() > 0) && !(tripleList.contains(tripleInDatabase))) { + tripleList.add(tripleInDatabase); + } + } + this.userInfo.setTerminalList(tripleList); + this.userInfo.update(); + + return this.userInfo; + } + + private List<String> selectStandardUa(List<String> uaList) { + List<String> standardUaList = getStandardUa(); + List<String> selectedUaList = new ArrayList<>(); + String windowsString = "Mozilla.*Windows"; + Pattern windows = Pattern.compile(windowsString); + for (String ua : uaList) { + if (windows.matcher(ua).find() && standardUaList.contains(ua)) { + selectedUaList.add(ua); + } + } + return selectedUaList; + } + + private List<String> getStandardUa() { + List<String> ua; + StandardUaList standardUaList = new StandardUaList(); + ua = standardUaList.getUaList(); + return ua; + } +}
\ No newline at end of file diff --git a/src/main/java/com/example/ua/config/ApplicationConfig.java b/src/main/java/com/example/ua/config/ApplicationConfig.java new file mode 100644 index 0000000..f22e594 --- /dev/null +++ b/src/main/java/com/example/ua/config/ApplicationConfig.java @@ -0,0 +1,26 @@ +package com.example.ua.config; + +import com.example.ua.utils.ConfigUtils; + + +/** + * 配置信息 + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public class ApplicationConfig { + + public static final String MARIADB_HOST = ConfigUtils.getStringProperty( "mariaDB.host"); + public static final String MARIADB_PORT = ConfigUtils.getStringProperty("mariaDB.port"); + public static final String MARIADB_USER = ConfigUtils.getStringProperty( "mariaDB.user"); + public static final String MARIADB_PASSWORD = ConfigUtils.getStringProperty( "mariaDB.password"); + public static final String MARIADB_DB_NAME = ConfigUtils.getStringProperty( "mariaDB.database"); + public static final String MARIADB_TABLE = ConfigUtils.getStringProperty( "mariaDB.talbe"); + + public static final String MARIA_UA = ConfigUtils.getStringProperty( "mariaDB.user_agent"); + public static final String MARIA_OS = ConfigUtils.getStringProperty( "mariaDB.os"); + public static final String MARIA_BROWSER = ConfigUtils.getStringProperty( "mariaDB.browser"); + public static final String MARIA_DIVECE = ConfigUtils.getStringProperty( "mariaDB.device"); + +} diff --git a/src/main/java/com/example/ua/dao/QueryMariaDb.java b/src/main/java/com/example/ua/dao/QueryMariaDb.java new file mode 100644 index 0000000..f8f9ec9 --- /dev/null +++ b/src/main/java/com/example/ua/dao/QueryMariaDb.java @@ -0,0 +1,20 @@ +package com.example.ua.dao; + +import org.mariadb.jdbc.MariaDbStatement; + +import java.util.List; + +/** + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public interface QueryMariaDb { + /** + * 接口函数 + * @param ua 查询ua + * @param connStatement conn + * @return 三元组(OS,browser device)结果 + */ + public List<String> getTriple(MariaDbStatement connStatement, String ua); +} diff --git a/src/main/java/com/example/ua/dao/impl/QueryMariaDbImpl.java b/src/main/java/com/example/ua/dao/impl/QueryMariaDbImpl.java new file mode 100644 index 0000000..3c32049 --- /dev/null +++ b/src/main/java/com/example/ua/dao/impl/QueryMariaDbImpl.java @@ -0,0 +1,61 @@ +package com.example.ua.dao.impl; + +import com.example.ua.config.ApplicationConfig; +import com.example.ua.dao.QueryMariaDb; +import org.mariadb.jdbc.MariaDbStatement; +import org.apache.log4j.Logger; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public class QueryMariaDbImpl implements QueryMariaDb { + private static final Logger LOG = Logger.getLogger(QueryMariaDbImpl.class); + + @Override + public List<String> getTriple(MariaDbStatement connStatement, String ua) { + String sql = getSqlPattern(ua); + List<String> triple = new ArrayList<>(); + + try{ + long startTime=System.currentTimeMillis(); + ResultSet results = connStatement.executeQuery(sql); + long endTime=System.currentTimeMillis(); + LOG.debug("QueryMaria.QueryTime " + (endTime-startTime) + "ms"); + + if (results.next()) { + results.previous(); + while (results.next()) { + triple.add(results.getString(ApplicationConfig.MARIA_OS)); + triple.add(results.getString(ApplicationConfig.MARIA_BROWSER)); + triple.add(results.getString(ApplicationConfig.MARIA_DIVECE)); + } + } else { + LOG.info("QueryMariaDB.Empty " + ua); + } + return triple; + + } catch (SQLException e){ + LOG.info("QueryMariaDB.Fail " + e.toString()); + return null; + } + } + + private String getSqlPattern(String ua){ + String sqlPattern = "SELECT "+ ApplicationConfig.MARIA_UA + ", " + + ApplicationConfig.MARIA_BROWSER + ", " + + ApplicationConfig.MARIA_OS + ", " + + ApplicationConfig.MARIA_DIVECE + " From " + + ApplicationConfig.MARIADB_DB_NAME + "." + + ApplicationConfig.MARIADB_TABLE + " WHERE user_agent = '%s'"; + return String.format(sqlPattern, ua); + } +} + + diff --git a/src/main/java/com/example/ua/utils/ConfigUtils.java b/src/main/java/com/example/ua/utils/ConfigUtils.java new file mode 100644 index 0000000..1a84ee5 --- /dev/null +++ b/src/main/java/com/example/ua/utils/ConfigUtils.java @@ -0,0 +1,43 @@ +package com.example.ua.utils; + +import org.apache.log4j.Logger; +import java.util.Properties; + +/** + * @author yjy + * @version 1.0 + * @date 2020/11/15 12:20 下午 + */ +public class ConfigUtils { + private static final Logger LOG = Logger.getLogger(ConfigUtils.class); + private static Properties propCommon = new Properties(); + + public static String getStringProperty(String key) { + return propCommon.getProperty(key); + } + + + public static Integer getIntProperty(String key) { + return Integer.parseInt(propCommon.getProperty(key)); + } + + public static Long getLongProperty(String key) { + return Long.parseLong(propCommon.getProperty(key)); + } + + public static Boolean getBooleanProperty(String key) { + return "true".equals(propCommon.getProperty(key).toLowerCase().trim()); + } + + static { + try { + propCommon.load(ConfigUtils.class.getClassLoader().getResourceAsStream("application.properties")); + LOG.info("application.properties加载成功"); + + + } catch (Exception e) { + propCommon = null; + LOG.error("配置加载失败"); + } + } +} diff --git a/src/main/java/com/example/ua/utils/MariaDBConnect.java b/src/main/java/com/example/ua/utils/MariaDBConnect.java new file mode 100644 index 0000000..cb95e51 --- /dev/null +++ b/src/main/java/com/example/ua/utils/MariaDBConnect.java @@ -0,0 +1,40 @@ +package com.example.ua.utils; + +import com.example.ua.config.ApplicationConfig; + +import org.mariadb.jdbc.MariaDbDataSource; +import org.mariadb.jdbc.MariaDbStatement; +//import org.slf4j.Logger; +import org.apache.log4j.Logger; +import org.slf4j.LoggerFactory; + +import org.mariadb.jdbc.MariaDbConnection; +import java.sql.SQLException; + +/** + * 建立连接 + */ +public class MariaDBConnect{ + private static final Logger LOG = Logger.getLogger(MariaDBConnect.class); + + public static MariaDbStatement getMariaDB(){ + String addr = "jdbc:mariadb://" + + ApplicationConfig.MARIADB_HOST + ":" + + ApplicationConfig.MARIADB_PORT + "/" + + ApplicationConfig.MARIADB_DB_NAME; + + MariaDbDataSource dataSource = new MariaDbDataSource(addr); + MariaDbStatement statement = null; + + try { + MariaDbConnection conn = (MariaDbConnection) dataSource.getConnection( + ApplicationConfig.MARIADB_USER, + ApplicationConfig.MARIADB_PASSWORD); + statement = (MariaDbStatement) conn.createStatement(); + } catch (SQLException e) { + LOG.error("GetMariaDBConnection Faild. " + e.toString()); + } + return statement; + } + +}
\ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..67d7f43 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,12 @@ +# mariaDB参数配置 +mariaDB.host = 192.168.40.193 +mariaDB.port = 3306 +mariaDB.user = tsg_query +mariaDB.password = ceiec_2018 +mariaDB.database = tsg_galaxy_source +mariaDB.talbe = whatismybrowser_useragent + +mariaDB.user_agent = user_agent +mariaDB.os = operating_system +mariaDB.browser = software +mariaDB.device = simple_operating_platform_string
\ No newline at end of file diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..15202b0 --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,26 @@ +########################## logger ############################## + +### 设置### +log4j.rootLogger = debug,stdout,D,E + +### 输出信息到控制抬 ### +#log4j.appender.stdout = org.apache.log4j.ConsoleAppender +#log4j.appender.stdout.Target = System.out +#log4j.appender.stdout.layout = org.apache.log4j.PatternLayout +#log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n + +### 输出DEBUG 级别以上的日志### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +log4j.appender.D.File = /Users/joy/work/iie/project/cyber_narrator/multiAccess/UaAnalyserV2/logs/debug.log +log4j.appender.D.Append = true +log4j.appender.D.Threshold = DEBUG +log4j.appender.D.layout = org.apache.log4j.PatternLayout +log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n + +### 输出ERROR 级别以上的日志 ### +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File =/Users/joy/work/iie/project/cyber_narrator/multiAccess/UaAnalyserV2/logs/error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
\ No newline at end of file diff --git a/src/test/java/UaAnalyserTest.java b/src/test/java/UaAnalyserTest.java new file mode 100644 index 0000000..b8c73d3 --- /dev/null +++ b/src/test/java/UaAnalyserTest.java @@ -0,0 +1,34 @@ +import com.example.ua.analyser.UaAnalyser; +import com.example.ua.analyser.enums.UserInfo; +import com.example.ua.analyser.impl.UaAnalyserImpl; +import com.example.ua.config.ApplicationConfig; + +import java.awt.*; +import java.lang.reflect.Field; + +public class UaAnalyserTest { + + + public static void main(String[] args){ + + String inputString = "69765" + "\t" + // userId + "192.168.50.13" + "\t" + // ip + "1765433230" + "\t" + // timeStamp + "'Dalvik/1.6.0 (Linux; U; Android 4.0.3; LG-E612f Build/IML74K)':4, " + + "'Dalvik/2.1.0 (Linux; U; Android 10; TNYAL00 Build/HUAWEITNY-AL00)':4" + + "'Mozilla/5.0 (iPhone; CPU iPhone OS 11_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15G77 === iOS/11.4.1 Model/iPhone10,1 BundleID/com.xunmeng.pinduoduo AppVersion/5.32.0 AppBuild/2009212125 pversion/1221 cURL/7.48.0':5" + + "'com.apple.trustd/1.0':1" + + "'server-bag [iPhone OS,13.6.1,17G80,iPhone10,2]':1" + + "'Microsoft-CryptoAPI/10.0':1" + + "'Mozilla/5.0 (Linux; Android 10; SM-G9600) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.110 Mobile Safari/537.36':10" + + "'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36':1"; // uaCntInfo + + UaAnalyser uaAnalyser = new UaAnalyserImpl(); + UserInfo userInfo = uaAnalyser.getUserinfo(inputString); + + // 获取相关字段: + // osCnt, browserCnt, deviceCnt, terminalCnt, terminalCatCnt, + // osList, browserList, deviceList, terminalList, terminalCatList + System.out.println(userInfo.getTerminalList()); // 获取terminalList字段值 + } +} |
