hbase入库

需求:抽取一批定向用户的号码

难点:运营商提供的数据用户号码等隐私字段都经过了脱敏处理,使用了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导入



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值