700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > CNN破解简单验证码(Tensorflow实现)

CNN破解简单验证码(Tensorflow实现)

时间:2021-11-15 18:40:49

相关推荐

CNN破解简单验证码(Tensorflow实现)

使用CNN破解一下自己生成的图片验证码,因为电脑性能不行,只破解四位的数字验证码,代码实现中可以对符号、字符和数字混合的验证码进行破解,原理相同,有高性能GPU的童鞋可以试试玩玩。CNN使用简单的三层卷积,人懒结构手绘如下图:

生成验证码的代码,使用了第三方库:

[python]view plaincopy #coding=utf-8importtensorflowastfimportnumpyasnpimportmatplotlib.pyplotasplt#condainstallPillowfromPILimportImageimportrandom#pipinstallcaptcha安装验证码库fromcaptcha.imageimportImageCaptcha#本代码生成验证码图片number=['0','1','2','3','4','5','6','7','8','9']alphabet=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']ALPHABET=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']defrandom_captcha_text(char_set=number+alphabet+ALPHABET,captcha_size=4):captcha_text=[]foriinrange(captcha_size):c=random.choice(char_set)captcha_text.append(c)returncaptcha_textdefgen_captcha_text_and_image():#构造captcha对象image=ImageCaptcha()captcha_text=random_captcha_text()#list->stringcaptcha_text=''.join(captcha_text)#生成图像验证码captcha=image.generate(captcha_text)#image.write(captcha_text,captcha_text+'.jpg')captcha_image=Image.open(captcha)#转换为numpuarray格式captcha_image=np.array(captcha_image)#返回Label和验证码returncaptcha_text,captcha_imageif__name__=='__main__':text,image=gen_captcha_text_and_image()f=plt.figure()ax=f.add_subplot(111)ax.text(0.1,0.9,text,ha='center',va='center',transform=ax.transAxes)plt.imshow(image)plt.show()

生成的效果如图:

验证码识别代码:

[python]view plaincopy #coding=utf-8importnumpyasnpimporttensorflowastffromcaptcha.imageimportImageCaptchaimportnumpyasnpimportmatplotlib.pyplotaspltfromPILimportImageimportrandomnumber=['0','1','2','3','4','5','6','7','8','9']#alphabet=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']#ALPHABET=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']#defrandom_captcha_text(char_set=number+alphabet+ALPHABET,captcha_size=4):#生成验证码文本defrandom_captcha_text(char_set=number,captcha_size=4):captcha_text=[]foriinrange(captcha_size):c=random.choice(char_set)captcha_text.append(c)returncaptcha_text#生成验证码图片(H*W*Chanel)和标签defgen_captcha_text_and_image():image=ImageCaptcha()captcha_text=random_captcha_text()captcha_text=''.join(captcha_text)captcha=image.generate(captcha_text)#image.write(captcha_text,captcha_text+'.jpg')captcha_image=Image.open(captcha)captcha_image=np.array(captcha_image)returncaptcha_text,captcha_imagedefconvert2gray(img):iflen(img.shape)>2:gray=np.mean(img,-1)#上面的转法较快,正规转法如下#r,g,b=img[:,:,0],img[:,:,1],img[:,:,2]#gray=0.2989*r+0.5870*g+0.1140*breturngrayelse:returnimgdeftext2vec(text):text_len=len(text)iftext_len>MAX_CAPTCHA:raiseValueError('验证码最长4个字符')vector=np.zeros(MAX_CAPTCHA*CHAR_SET_LEN)"""defchar2pos(c):ifc=='_':k=62returnkk=ord(c)-48ifk>9:k=ord(c)-55ifk>35:k=ord(c)-61ifk>61:raiseValueError('NoMap')returnk"""fori,cinenumerate(text):idx=i*CHAR_SET_LEN+int(c)vector[idx]=1returnvector#向量转回文本defvec2text(vec):"""char_pos=vec.nonzero()[0]text=[]fori,cinenumerate(char_pos):char_at_pos=i#c/63char_idx=c%CHAR_SET_LENifchar_idx<10:char_code=char_idx+ord('0')elifchar_idx<36:char_code=/-10+ord('A')elifchar_idx<62:char_code=char_idx-36+ord('a')elifchar_idx==62:char_code=ord('_')else:raiseValueError('error')text.append(chr(char_code))"""text=[]char_pos=vec.nonzero()[0]fori,cinenumerate(char_pos):number=i%10text.append(str(number))return"".join(text)"""#向量(大小MAX_CAPTCHA*CHAR_SET_LEN)用0,1编码每63个编码一个字符,这样顺利有,字符也有vec=text2vec("F5Sd")text=vec2text(vec)print(text)#F5Sdvec=text2vec("SFd5")text=vec2text(vec)print(text)#SFd5"""#生成一个训练batchdefget_next_batch(batch_size=128):batch_x=np.zeros([batch_size,IMAGE_HEIGHT*IMAGE_WIDTH])batch_y=np.zeros([batch_size,MAX_CAPTCHA*CHAR_SET_LEN])#有时生成图像大小不是(60,160,3)defwrap_gen_captcha_text_and_image():whileTrue:text,image=gen_captcha_text_and_image()ifimage.shape==(60,160,3):returntext,imageforiinrange(batch_size):text,image=wrap_gen_captcha_text_and_image()image=convert2gray(image)batch_x[i,:]=image.flatten()/255#(image.flatten()-128)/128mean为0batch_y[i,:]=text2vec(text)returnbatch_x,batch_y#定义CNN#w_alpha,b_alpha传入一个很小的值作为初始化值defcrack_captcha_cnn(w_alpha=0.01,b_alpha=0.1):#传入的X为[batch_size,H,W],需要转换为Tensorflow格式[batch_size,H,W,Chanel]x=tf.reshape(X,shape=[-1,IMAGE_HEIGHT,IMAGE_WIDTH,1])#w_c1_alpha=np.sqrt(2.0/(IMAGE_HEIGHT*IMAGE_WIDTH))##w_c2_alpha=np.sqrt(2.0/(3*3*32))#w_c3_alpha=np.sqrt(2.0/(3*3*64))#w_d1_alpha=np.sqrt(2.0/(8*32*64))#out_alpha=np.sqrt(2.0/1024)#3convlayer#filter:3*3,输入通道1(灰度图),输出(特征图):32w_c1=tf.Variable(w_alpha*tf.random_normal([3,3,1,32]))b_c1=tf.Variable(b_alpha*tf.random_normal([32]))conv1=tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, c1,strides=[1,1,1,1],padding='SAME'),b_c1))conv1=tf.nn.max_pool(conv1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')conv1=tf.nn.dropout(conv1,keep_prob)w_c2=tf.Variable(w_alpha*tf.random_normal([3,3,32,64]))b_c2=tf.Variable(b_alpha*tf.random_normal([64]))conv2=tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1,w_c2,strides=[1,1,1,1],padding='SAME'),b_c2))conv2=tf.nn.max_pool(conv2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')conv2=tf.nn.dropout(conv2,keep_prob)w_c3=tf.Variable(w_alpha*tf.random_normal([3,3,64,64]))b_c3=tf.Variable(b_alpha*tf.random_normal([64]))conv3=tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2,w_c3,strides=[1,1,1,1],padding='SAME'),b_c3))conv3=tf.nn.max_pool(conv3,ksize=[1,2,2,/1],strides=[1,2,2,1],padding='SAME')conv3=tf.nn.dropout(conv3,keep_prob)#Fullyconnectedlayerw_d=tf.Variable(w_alpha*tf.random_normal([8*20*64,1024]))b_d=tf.Variable(b_alpha*tf.random_normal([1024]))#卷积结果扁平化dense=tf.reshape(conv3,[-1,w_d.get_shape().as_list()[0]])dense=tf.nn.relu(tf.add(tf.matmul(dense,w_d),b_d))dense=tf.nn.dropout(dense,keep_prob)w_out=tf.Variable(w_alpha*tf.random_normal([1024,MAX_CAPTCHA*CHAR_SET_LEN]))b_out=tf.Variable(b_alpha*tf.random_normal([ CAPTCHA*CHAR_SET_LEN]))out=tf.add(tf.matmul(dense,w_out),b_out)returnout#训练deftrain_crack_captcha_cnn():#三层CNN预测输出output=crack_captcha_cnn()loss=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output,labels=Y))optimizer=tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)predict=tf.reshape(output,[-1,MAX_CAPTCHA,CHAR_SET_LEN])max_idx_p=tf.argmax(predict,2)max_idx_l=tf.argmax(tf.reshape(Y,[-1,MAX_CAPTCHA,CHAR_SET_LEN]),2)correct_pred=tf.equal(max_idx_p, l)accuracy=tf.reduce_mean(tf.cast(correct_pred,tf.float32))saver=tf.train.Saver()withtf.Session()assess:sess.run(tf.global_variables_initializer())step=0whileTrue:batch_x,batch_y=get_next_batch(64)_,loss_=sess.run([optimizer,loss], feed_dict={X:batch_x,Y:batch_y,keep_prob:0.75})print(step,loss_)#每100step计算一次准确率ifstep%10==0:batch_x_test,batch_y_test=get_next_batch(100)acc=sess.run(accuracy,feed_dict={X:batch_x_test,Y:batch_y_test,keep_prob:1.})print(step,acc)#如果准确率大于50%,保存模型,完成训练ifacc>0.50:saver.save(sess,"./model/ capcha.model",global_step=step)breakstep+=1defcrack_captcha(captcha_image):output=crack_captcha_cnn()saver=tf.train.Saver()withtf.Session()assess:saver.restore(sess,"./model/crack_capcha.model-810")predict=tf.argmax(tf.reshape(output,[-1,MAX_CAPTCHA,CHAR_SET_LEN]),2)text_list=sess.run(predict,feed_dict={X:[captcha_image],keep_prob:1})text=text_list[0].tolist()returntextif__name__=='__main__':#定义train变量,train=0:网络测试,train=1:网络训练train=0iftrain==0:number=['0','1','2','3','4','5','6','7','8','9']#没有GPU,为加快训练速度,暂时只训练仅含数字的验证码#alphabet=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']#ALPHABET=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']text,image=gen_captcha_text_and_image()print("验证码图像channel:",image.shape)#(60,160,3)#图像大小IMAGE_HEIGHT=60IMAGE_WIDTH=160MAX_CAPTCHA=len(text)print("验证码文本最长字符数",MAX_CAPTCHA)#文本转向量#char_set=number+alphabet+ALPHABET+['_']#如果验证码长度小于4,'_'用来补齐char_set=numberCHAR_SET_LEN=len(char_set)#验证码识别中,颜色用处不大,因此将彩色图转换为灰度图,加快训练速度X=tf.placeholder(tf.float32,[None,IMAGE_HEIGHT*IMAGE_WIDTH])#60*160#四位验证码:采用四组10位的one-hotY=tf.placeholder(tf.float32,[None,MAX_CAPTCHA*CHAR_SET_LEN])#4*10#dropoutkeep_prob=tf.placeholder(tf.float32)train_crack_captcha_cnn()iftrain==1:number=['0','1','2','3','4','5','6','7','8','9']IMAGE_HEIGHT=60IMAGE_WIDTH=160char_set=numberCHAR_SET_LEN=len(char_set)text,image=gen_captcha_text_and_image()f=plt.figure()ax=f.add_subplot(111)ax.text(0.1,0.9,text,ha='center',va='center',transform=ax.transAxes)plt.imshow(image)plt.show()MAX_CAPTCHA=len(text)image=convert2gray(image)image=image.flatten()/255X=tf.placeholder(tf.float32,[None,IMAGE_HEIGHT*IMAGE_WIDTH])Y=tf.placeholder(tf.float32,[None,MAX_CAPTCHA*CHAR_SET_LEN])keep_prob=tf.placeholder(tf.float32)#dropoutpredict_text=crack_captcha(image)print("正确:{}预测:{}".format(text,predict_text))

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。