您的位置:首页 > 其它

hbase入库

2016-02-17 11:29 363 查看
需求:抽取一批定向用户的号码

难点:运营商提供的数据用户号码等隐私字段都经过了脱敏处理,使用了MD5加密

解决:

方案一:部分url字段中包含了用户号码的明文字段,可以从中提取。

方案二:根据电信号码的编码规律得到所有电信号码以及其对应的MD5编码,通过撞库可以获取指定用户的号码。

<pre name="code" class="plain">


hadoop dfs -text /daas/bstl/dpiqixin/beijing/20151115/MBLDPI.2015111523.7.1447602727877.lzo_deflate | grep --color 'phone=' |cut -d \| -f2,28


将明文经过md5加密,和运营商的加密后的号码字段匹配,如果匹配成功,则提取正确。

md5加密代码:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class ParseMD5 {

/**
* @param str
* @return
* @Date: 2013-9-6
* @Author: lulei
* @Description:  32位小写MD5
*/
public static String parseStrToMd5L32(String str){
String reStr = null;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest(str.getBytes());
StringBuffer stringBuffer = new StringBuffer();
for (byte b : bytes){
int bt = b&0xff;
if (bt < 16){
stringBuffer.append(0);
}
stringBuffer.append(Integer.toHexString(bt));
}
reStr = stringBuffer.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return reStr;
}

/**
* @param str
* @return
* @Date: 2013-9-6
* @Author: lulei
* @Description: 32位大写MD5
*/
public static String parseStrToMd5U32(String str){
String reStr = parseStrToMd5L32(str);
if (reStr != null){
reStr = reStr.toUpperCase();
}
return reStr;
}

/**
* @param str
* @return
* @Date: 2013-9-6
* @Author: lulei
* @Description: 16位小写MD5
*/
public static String parseStrToMd5U16(String str){
String reStr = parseStrToMd5L32(str);
if (reStr != null){
reStr = reStr.toUpperCase().substring(8, 24);
}
return reStr;
}

/**
* @param str
* @return
* @Date: 2013-9-6
* @Author: lulei
* @Description: 16位大写MD5
*/
public static String parseStrToMd5L16(String str){
String reStr = parseStrToMd5L32(str);
if (reStr != null){
reStr = reStr.substring(8, 24);
}
return reStr;
}

public static void main(String[] args) {
String md5str="A8D549CC736F231536386A1673A53B95";
String phone="13381231629";
//		System.out.println(md5str.length());
String md5str2=parseStrToMd5U32(phone);
System.out.println(md5str2.equals(md5str));
}
}


方法二探究:

中国电信手机号码开头数字

2G/3G号段(CDMA2000网络)133、153、180、181、189

4G号段 177、173

编码规则都是人定的。大陆的手机号码是11位,而香港的手机号码只有8位。大陆的编码规则为:

前3位:网络识别号,如134-139、158、159属中国移动;130-132、156属中国联通。

  第4~7位(中四位):地区编码,如0252代表湖南省长沙市。一些网站和手机APP可以查归属地就是根据这个数据库。

  第8~11位(后四位):用户号码,从0000至9999,每段1万户。

附手机号码区域查询库:

1、初始数据在Data.mdb文件中,需要导出为dainxin.txt文件才能进行处理

2、为了方便,在linux中用grep命令和重定向得到只包含电信数据的初始文件

3、用java生成需要的库文件

public class NumProducer {
public static void main(String[] args) throws Exception {
List<String> prefix = DianxinList.elements();
List<String> sufix = getSufix();
List<String> nums=new ArrayList<>();
String num=null;
String local="";
FileWriter writer=new FileWriter(new File("dianxin"));
for (String each : prefix) {
String pre=each.split(",")[1];
pre=pre.substring(1, pre.length()-1);
local=each.split(",")[2];
local=local.substring(1, local.length()-1);
for (String suf : sufix) {
num=pre+suf;
String md5str=ParseMD5.parseStrToMd5U32(num);
writer.write(num+","+md5str+","+local+"\r\n");
//				nums.add(num);
//				System.out.println(num);
}
//			System.out.println(pre.subSequence(1, pre.length()-1));
}

writer.close();

}

public static List<String> getSufix(){
List<String> result=new ArrayList<>();
for(int i=0;i<10000;i++){
String num=String.format("%04d", i);
result.add(num);
//			System.out.println(num);
}
return result;
}

}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DianxinList {

private static final String FILE_NAME = "dianxin2";

private static List<String> url_parse_param = new ArrayList<String>();

static {
File file = new File(System.getProperty("user.dir") + "/" + FILE_NAME);
if (file.exists()) {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
while ((line = br.readLine()) != null) {
url_parse_param.add(line);
}

} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

public static List<String> elements() {
return url_parse_param;
}

public static Map<String, String> getParserMap(){
Map<String, String> map=new HashMap<>();

List<String> es = DianxinList.elements();
for (String each : es) {
String name=each.split("\\|")[0];
map.put(name, each);
}
return map;
}

}


4、为了方便查询,将数据用hbase入库

hbase创建表

create 'ee_dianxin_phone','info'


5、导入:其中-Dmapreduce.job.queuename=dmp1是队列的设置,间隔符号是逗号,第一个字段定位rowkey,后面字段对应指定的列中

hbase org.apache.hadoop.hbase.mapreduce.ImportTsv  -Dmapreduce.job.queuename=dmp1 -Dimporttsv.separator="," -Dimporttsv.columns=HBASE_ROW_KEY,info:md5code,info:local ee_dianxin_phone /user/chenjinghui


更多关于hbase的导入:hbase导入
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: