Python Random 函数在批量造数据中的运用

kisom · 2020年12月08日 · 最后由 guolong123 回复于 2020年12月15日 · 2211 次阅读

random 函数作为 python 中生成随机数据的主要函数,在我们造数据的过程中有着非常广阔的应用
以下是 random 函数的几种主要用法:

print( random.randint(1,10) )        # 产生 1 到 10 的一个整数型随机数  
print( random.random() )             # 产生 0 到 1 之间的随机浮点数
print( random.uniform(1.1,5.4) )     # 产生  1.1 到 5.4 之间的随机浮点数,区间可以不是整数
print( random.choice('tomorrow') )   # 从序列中随机选取一个元素
print( random.randrange(1,100,2) )   # 生成从1到100的间隔为2的随机整数
print random.sample('zyxwvnmlkjihgfedcba',5)  # 多个字符中生成指定数量的随机字符

我以自己刚在新公司写的一个脚本为例:需要批量生成 C 端的账号,我需要每次生成随机的手机号、身份证号再去调注册接口、认证接口。批量生成随机的手机号和身份证号会有很多应用到 Random 函数的地方。
手机号码:3 位前缀 +8 位随机数字
随机取 3 位前缀:

list = ['130','134','135','137','139','181','188','189']
        temp = random.choice(list)

8 位随机数字,这里提供 2 种写法:

mobile = temp+''.join(random.choice("0123456789") for i in range(8))
mobile = temp + ''.join(random.sample(string.digits,8))

身份证号码:6 位地区码 + 出生日期 + 三位随机数 + 权重位
6 位地区码,如果想取值范围广一些,大家可以把地区码写到.txt 或者 excel 里面去读取,我这里就随机列了一些地区码去取:

arealist = [ "440301","370600", "370601", "370602", "370611", "370612", "370613", "370634", "370681",
                                 "370682", "370683", ]
area = random.choice(arealist)

随机生成出生日期,这里我的方法是在一个范围区间随机取一个时间戳,但是 time.mktime() 方法有个坑,不能输入 1970 年之前的日期:

start = (1971, 1, 17, 17, 3, 38, 1, 48, 0)
end = (2001, 12, 1, 12, 10, 10, 10, 10, 10)
start_time = time.mktime(start)
end_time = time.mktime(end)
s = random.randint(start_time,end_time)
toule = time.localtime(s)
birth = time.strftime("%Y%m%d",toule)

生成 3 位随机数:

d = random.randint(100,999)

最后一位权重码计算:

temp = area+str(birth)+str(id)
        count=0
        weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
        checkcode = {0:'1',1:'0', 2:'X', 3:'9',4:'8',5:'7',6:'6',7:'5',8:'4',9:'3',10:'2'}
        for i in range(0,len(temp)):
            tes = int(temp[i])
            count = count+tes*weight[i]
        last = count%11
        lastcode = checkcode[last]
        IDcard = temp + ''.join(lastcode)
共收到 15 条回复 时间 点赞
kisom 回复

faker 可以写自定义造数据方法的。而且你这上面造的数据 faker 都能造.......

faker 不就能直接生成手机号,身份证嘛

kisom 回复

我跟 9 楼同问,+1 也不麻烦,random 比起 +1 的优点是什么?

kisom #12 · 2020年12月11日 Author
Thirty-Thirty 回复

朋友你可能没测过轧差吧。假设你单笔实际的佣金是 0.0403,一般单笔佣金分账都会四舍五入取小数点后 2 位,就是 0.04,最后订单完结时要算轧差,这种情况只有成交大于等于 17 笔,0.0003*17=0.0051,四舍五入 0.01,这个时候轧差才会有金额,根据系统小数点后保留的位数,轧差计算的复杂度会差很多,这种虽然也是属于功能测试,但你不拿类似这种脚本辅助测到哭为止。

kisom 回复

身份证都要要做有效性的正则校验 ---- 涨知识了。
暂时遇到的需求就是校验姓名和身份证是否符合,只考虑了符合和不符合的测试点,后续遇到你这样的场景就知道要正则校验了~棒 (๑•̀ㅂ•́)و✧

Mango 回复

1.怕撞到已注册的号码,你再多加一步判断,查下号码是否在数据库中已存在就好;
2.每次 +1 这么玩也不是不可以;
3.一般来说身份证都要要做有效性的正则校验,如果你们开发就判断个 18 位其实是可以提 bug 的;我造的数据都是符合身份证正则规则的,所以接口校验都是能过的,至于你说的可能这个身份证不存在的问题,除非你们调了公安那边的接口,否则你们是无法校验身份证是否真实存在。一般来说,二要素检查(姓名 + 身份证)不一定会校验身份证的真实性,三要素检查(姓名 + 身份证 + 活体)会去调公安的接口比较多。

有几个疑问,小点工一枚,还请楼主答疑~
1.涉及注册:脚本运行环境非线上吧?测试服的数据有没有定时同步正式服?如果有的话,感觉随机撞到已注册的号码的几率比较大。
2.不太懂为什么一定要 random 去生成数据,目前看来好像对手机号和身份证的真实性没有做检验。我个人的做法可能会是直接从 19000000001 开始,每次用手机号就 +1...想知道用 random 的优点~
3.身份证格式楼主都有特意设定 6 位地区码之类,我感觉如果不对身份证做检验的话,不一定需要设置这么多条件,直接随机个 18 位字符串就可以达到期望了。如果做检验,随机出来的身份证可能不存在,影响到脚本的判断

kisom 回复

这个场景还是在做功能验证,跟用户注册一样,用少量的账号数据就可以了,不需要大批量验证啊!

Thirty-Thirty 回复

不是在做性能,我说一下我这边的场景:我们这边 C 端用户购买产品后,我们需要给用户分账且我们这边会收单笔的佣金,最后订单完成还需要记一笔佣金轧差。而且这些我们都是要掉第三方支付的接口,我需要试下大批量用户交易成功,看下分账情况及轧差。当然也可以拿来做性能测试,放到 linux 环境多线程去调接口。

kisom 回复

是在做性能测试吗?

Thirty-Thirty 回复

没有具体的数目,这次批量建了 500 个账号,我现在的脚本是生成多少账号随我自己定。这次生成账号主要是为了协助产品那边与数据源对接;后面可能还会再造一批数据,再写个调交易接口的脚本,用于模拟大批量用户购买某个产品的场景。

问下,你需要批量生成多少账号?

faker 确实是省时省力,但是有些数据也造不了,互补一下

faker 有些数据造不了,好像身份证就不行

直接用 faker 省时省力

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册