keras入门(三)搭建CNN模型破解网站验证码

news/2024/4/28 16:30:54/文章来源:https://blog.csdn.net/weixin_34138139/article/details/88727110

项目介绍

  在文章CNN大战验证码中,我们利用TensorFlow搭建了简单的CNN模型来破解某个网站的验证码。验证码如下:

网站验证码

在本文中,我们将会用Keras来搭建一个稍微复杂的CNN模型来破解以上的验证码。

数据集

  对于验证码图片的处理过程在本文中将不再具体叙述,有兴趣的读者可以参考文章CNN大战验证码。
  在这个项目中,我们现在的样本一共是1668个样本,每个样本都是一个字符图片,字符图片的大小为16*20。样本的特征为字符图片的像素,0代表白色,1代表黑色,每个样本为320个特征,取值为0或1,特征变量名称为v1到v320,样本的类别标签即为该字符。整个数据集的部分如下:

data.csv(部分)

CNN模型

  利用Keras可以快速方便地搭建CNN模型,本文搭建的CNN模型如下:

将数据集分为训练集和测试集,占比为8:2,该模型训练的代码如下:

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from matplotlib import pyplot as pltfrom keras.utils import np_utils, plot_model
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.callbacks import EarlyStopping
from keras.layers import Conv2D, MaxPooling2D# 读取数据
df = pd.read_csv('F://verifycode_data/data.csv')# 标签值
vals = range(31)
keys = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','L','N','P','Q','R','S','T','U','V','X','Y','Z']
label_dict = dict(zip(keys, vals))x_data = df[['v'+str(i+1) for i in range(320)]]
y_data = pd.DataFrame({'label':df['label']})
y_data['class'] = y_data['label'].apply(lambda x: label_dict[x])# 将数据分为训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(x_data, y_data['class'], test_size=0.3, random_state=42)
x_train = np.array(X_train).reshape((1167, 20, 16, 1))
x_test = np.array(X_test).reshape((501, 20, 16, 1))# 对标签值进行one-hot encoding
n_classes = 31
y_train = np_utils.to_categorical(Y_train, n_classes)
y_val = np_utils.to_categorical(Y_test, n_classes)input_shape = x_train[0].shape# CNN模型
model = Sequential()# 卷积层和池化层
model.add(Conv2D(32, kernel_size=(3, 3), input_shape=input_shape, padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(32, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))# Dropout层
model.add(Dropout(0.25))model.add(Conv2D(64, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))model.add(Dropout(0.25))model.add(Conv2D(128, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(128, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))model.add(Dropout(0.25))model.add(Flatten())# 全连接层
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(128, activation='relu'))
model.add(Dense(n_classes, activation='softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])# plot model
plot_model(model, to_file=r'./model.png', show_shapes=True)# 模型训练
callbacks = [EarlyStopping(monitor='val_acc', patience=5, verbose=1)]
batch_size = 64
n_epochs = 100
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=n_epochs, \verbose=1, validation_data=(x_test, y_val), callbacks=callbacks)mp = 'F://verifycode_data/verifycode_Keras.h5'
model.save(mp)# 绘制验证集上的准确率曲线
val_acc = history.history['val_acc']
plt.plot(range(len(val_acc)), val_acc, label='CNN model')
plt.title('Validation accuracy on verifycode dataset')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.legend()
plt.show()

在上述代码中,我们训练模型的时候采用了early stopping技巧。early stopping是用于提前停止训练的callbacks。具体地,可以达到当训练集上的loss不在减小(即减小的程度小于某个阈值)的时候停止继续训练。

模型训练

  运行上述模型训练代码,输出的结果如下:

......(忽略之前的输出)
Epoch 22/10064/1167 [>.............................] - ETA: 3s - loss: 0.0399 - acc: 1.0000128/1167 [==>...........................] - ETA: 3s - loss: 0.1195 - acc: 0.9844192/1167 [===>..........................] - ETA: 2s - loss: 0.1085 - acc: 0.9792256/1167 [=====>........................] - ETA: 2s - loss: 0.1132 - acc: 0.9727320/1167 [=======>......................] - ETA: 2s - loss: 0.1045 - acc: 0.9750384/1167 [========>.....................] - ETA: 2s - loss: 0.1006 - acc: 0.9740448/1167 [==========>...................] - ETA: 2s - loss: 0.1522 - acc: 0.9643512/1167 [============>.................] - ETA: 1s - loss: 0.1450 - acc: 0.9648576/1167 [=============>................] - ETA: 1s - loss: 0.1368 - acc: 0.9653640/1167 [===============>..............] - ETA: 1s - loss: 0.1353 - acc: 0.9641704/1167 [=================>............] - ETA: 1s - loss: 0.1280 - acc: 0.9659768/1167 [==================>...........] - ETA: 1s - loss: 0.1243 - acc: 0.9674832/1167 [====================>.........] - ETA: 0s - loss: 0.1577 - acc: 0.9639896/1167 [======================>.......] - ETA: 0s - loss: 0.1488 - acc: 0.9665960/1167 [=======================>......] - ETA: 0s - loss: 0.1488 - acc: 0.9656
1024/1167 [=========================>....] - ETA: 0s - loss: 0.1427 - acc: 0.9668
1088/1167 [==========================>...] - ETA: 0s - loss: 0.1435 - acc: 0.9669
1152/1167 [============================>.] - ETA: 0s - loss: 0.1383 - acc: 0.9688
1167/1167 [==============================] - 4s 3ms/step - loss: 0.1380 - acc: 0.9683 - val_loss: 0.0835 - val_acc: 0.9760
Epoch 00022: early stopping

可以看到,一共训练了21次,最近一次的训练后,在测试集上的准确率为96.83%。在测试集的准确率曲线如下图:

测试集上的准确率曲线

模型预测

  模型训练完后,我们对新的验证码进行预测。新的100张验证码如下图:

新的验证码(部分)

  使用训练好的CNN模型,对这些新的验证码进行预测,预测的Python代码如下:

# -*- coding: utf-8 -*-import os
import cv2
import numpy as npdef split_picture(imagepath):# 以灰度模式读取图片gray = cv2.imread(imagepath, 0)# 将图片的边缘变为白色height, width = gray.shapefor i in range(width):gray[0, i] = 255gray[height-1, i] = 255for j in range(height):gray[j, 0] = 255gray[j, width-1] = 255# 中值滤波blur = cv2.medianBlur(gray, 3) #模板大小3*3# 二值化ret,thresh1 = cv2.threshold(blur, 200, 255, cv2.THRESH_BINARY)# 提取单个字符chars_list = []image, contours, hierarchy = cv2.findContours(thresh1, 2, 2)for cnt in contours:# 最小的外接矩形x, y, w, h = cv2.boundingRect(cnt)if x != 0 and y != 0 and w*h >= 100:chars_list.append((x,y,w,h))sorted_chars_list = sorted(chars_list, key=lambda x:x[0])for i,item in enumerate(sorted_chars_list):x, y, w, h = itemcv2.imwrite('F://test_verifycode/chars/%d.jpg'%(i+1), thresh1[y:y+h, x:x+w])def remove_edge_picture(imagepath):image = cv2.imread(imagepath, 0)height, width = image.shapecorner_list = [image[0,0] < 127,image[height-1, 0] < 127,image[0, width-1]<127,image[ height-1, width-1] < 127]if sum(corner_list) >= 3:os.remove(imagepath)def resplit_with_parts(imagepath, parts):image = cv2.imread(imagepath, 0)os.remove(imagepath)height, width = image.shapefile_name = imagepath.split('/')[-1].split(r'.')[0]# 将图片重新分裂成parts部分step = width//parts     # 步长start = 0             # 起始位置for i in range(parts):cv2.imwrite('F://test_verifycode/chars/%s.jpg'%(file_name+'-'+str(i)), \image[:, start:start+step])start += stepdef resplit(imagepath):image = cv2.imread(imagepath, 0)height, width = image.shapeif width >= 64:resplit_with_parts(imagepath, 4)elif width >= 48:resplit_with_parts(imagepath, 3)elif width >= 26:resplit_with_parts(imagepath, 2)# rename and convert to 16*20 size
def convert(dir, file):imagepath = dir+'/'+file# 读取图片image = cv2.imread(imagepath, 0)# 二值化ret, thresh = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)img = cv2.resize(thresh, (16, 20), interpolation=cv2.INTER_AREA)# 保存图片cv2.imwrite('%s/%s' % (dir, file), img)# 读取图片的数据,并转化为0-1值
def Read_Data(dir, file):imagepath = dir+'/'+file# 读取图片image = cv2.imread(imagepath, 0)# 二值化ret, thresh = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)# 显示图片bin_values = [1 if pixel==255 else 0 for pixel in thresh.ravel()]return bin_valuesdef predict(VerifyCodePath):dir = 'F://test_verifycode/chars'files = os.listdir(dir)# 清空原有的文件if files:for file in files:os.remove(dir + '/' + file)split_picture(VerifyCodePath)files = os.listdir(dir)if not files:print('查看的文件夹为空!')else:# 去除噪声图片for file in files:remove_edge_picture(dir + '/' + file)# 对黏连图片进行重分割for file in os.listdir(dir):resplit(dir + '/' + file)# 将图片统一调整至16*20大小for file in os.listdir(dir):convert(dir, file)# 图片中的字符代表的向量files = sorted(os.listdir(dir), key=lambda x: x[0])table = np.array([Read_Data(dir, file) for file in files]).reshape(-1,20,16,1)# 模型保存地址mp = 'F://verifycode_data/verifycode_Keras.h5'# 载入模型from keras.models import load_modelcnn = load_model(mp)# 模型预测y_pred = cnn.predict(table)predictions = np.argmax(y_pred, axis=1)# 标签字典keys = range(31)vals = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'N','P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z']label_dict = dict(zip(keys, vals))return ''.join([label_dict[pred] for pred in predictions])def main():dir = 'F://VerifyCode/'correct = 0for i, file in enumerate(os.listdir(dir)):true_label = file.split('.')[0]VerifyCodePath = dir+filepred = predict(VerifyCodePath)if true_label == pred:correct += 1print(i+1, (true_label, pred), true_label == pred, correct)total = len(os.listdir(dir))print('\n总共图片:%d张\n识别正确:%d张\n识别准确率:%.2f%%.'\%(total, correct, correct*100/total))main()

以下是该CNN模型的预测结果:

Using TensorFlow backend.
2018-10-25 15:13:50.390130: I C:\tf_jenkins\workspace\rel-win\M\windows\PY\35\tensorflow\core\platform\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
1 ('ZK6N', 'ZK6N') True 1
2 ('4JPX', '4JPX') True 2
3 ('5GP5', '5GP5') True 3
4 ('5RQ8', '5RQ8') True 4
5 ('5TQP', '5TQP') True 5
6 ('7S62', '7S62') True 6
7 ('8R2Z', '8R2Z') True 7
8 ('8RFV', '8RFV') True 8
9 ('9BBT', '9BBT') True 9
10 ('9LNE', '9LNE') True 10
11 ('67UH', '67UH') True 11
12 ('74UK', '74UK') True 12
13 ('A5T2', 'A5T2') True 13
14 ('AHYV', 'AHYV') True 14
15 ('ASEY', 'ASEY') True 15
16 ('B371', 'B371') True 16
17 ('CCQL', 'CCQL') True 17
18 ('CFD5', 'GFD5') False 17
19 ('CJLJ', 'CJLJ') True 18
20 ('D4QV', 'D4QV') True 19
21 ('DFQ8', 'DFQ8') True 20
22 ('DP18', 'DP18') True 21
23 ('E3HC', 'E3HC') True 22
24 ('E8VB', 'E8VB') True 23
25 ('DE1U', 'DE1U') True 24
26 ('FK1R', 'FK1R') True 25
27 ('FK91', 'FK91') True 26
28 ('FSKP', 'FSKP') True 27
29 ('FVZP', 'FVZP') True 28
30 ('GC6H', 'GC6H') True 29
31 ('GH62', 'GH62') True 30
32 ('H9FQ', 'H9FQ') True 31
33 ('H67Q', 'H67Q') True 32
34 ('HEKC', 'HEKC') True 33
35 ('HV2B', 'HV2B') True 34
36 ('J65Z', 'J65Z') True 35
37 ('JZCX', 'JZCX') True 36
38 ('KH5D', 'KH5D') True 37
39 ('KXD2', 'KXD2') True 38
40 ('1GDH', '1GDH') True 39
41 ('LCL3', 'LCL3') True 40
42 ('LNZR', 'LNZR') True 41
43 ('LZU5', 'LZU5') True 42
44 ('N5AK', 'N5AK') True 43
45 ('N5Q3', 'N5Q3') True 44
46 ('N96Z', 'N96Z') True 45
47 ('NCDG', 'NCDG') True 46
48 ('NELS', 'NELS') True 47
49 ('P96U', 'P96U') True 48
50 ('PD42', 'PD42') True 49
51 ('PECG', 'PEQG') False 49
52 ('PPZF', 'PPZF') True 50
53 ('PUUL', 'PUUL') True 51
54 ('Q2DN', 'D2DN') False 51
55 ('QCQ9', 'QCQ9') True 52
56 ('QDB1', 'QDBJ') False 52
57 ('QZUD', 'QZUD') True 53
58 ('R3T5', 'R3T5') True 54
59 ('S1YT', 'S1YT') True 55
60 ('SP7L', 'SP7L') True 56
61 ('SR2K', 'SR2K') True 57
62 ('SUP5', 'SVP5') False 57
63 ('T2SP', 'T2SP') True 58
64 ('U6V9', 'U6V9') True 59
65 ('UC9P', 'UC9P') True 60
66 ('UFYD', 'UFYD') True 61
67 ('V9NJ', 'V9NH') False 61
68 ('V35X', 'V35X') True 62
69 ('V98F', 'V98F') True 63
70 ('VD28', 'VD28') True 64
71 ('YGHE', 'YGHE') True 65
72 ('YNKD', 'YNKD') True 66
73 ('YVXV', 'YVXV') True 67
74 ('ZFBS', 'ZFBS') True 68
75 ('ET6X', 'ET6X') True 69
76 ('TKVC', 'TKVC') True 70
77 ('2UCU', '2UCU') True 71
78 ('HNBK', 'HNBK') True 72
79 ('X8FD', 'X8FD') True 73
80 ('ZGNX', 'ZGNX') True 74
81 ('LQCU', 'LQCU') True 75
82 ('JNZY', 'JNZVY') False 75
83 ('RX34', 'RX34') True 76
84 ('811E', '811E') True 77
85 ('ETDX', 'ETDX') True 78
86 ('4CPR', '4CPR') True 79
87 ('FE91', 'FE91') True 80
88 ('B7XH', 'B7XH') True 81
89 ('1RUA', '1RUA') True 82
90 ('UBCX', 'UBCX') True 83
91 ('KVT5', 'KVT5') True 84
92 ('HZ3A', 'HZ3A') True 85
93 ('3XLR', '3XLR') True 86
94 ('VC7T', 'VC7T') True 87
95 ('7PG1', '7PQ1') False 87
96 ('4F21', '4F21') True 88
97 ('3HLJ', '3HLJ') True 89
98 ('1KT7', '1KT7') True 90
99 ('1RHE', '1RHE') True 91
100 ('1TTA', '1TTA') True 92总共图片:100张
识别正确:92张
识别准确率:92.00%.

可以看到,该训练后的CNN模型,其预测新验证的准确率在90%以上。

总结

  在文章CNN大战验证码中,笔者使用TensorFlow搭建了CNN模型,代码较长,训练时间在两个小时以上,而使用Keras搭建该模型,代码简洁,且使用early stopping技巧后能缩短训练时间,同时保证模型的准确率,由此可见Keras的优势所在。
  该项目已开源,Github地址为:https://github.com/percent4/C...。

注意:本人现已开通微信公众号: Python爬虫与算法(微信号为:easy_web_scrape), 欢迎大家关注哦~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_704349.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python、语言的主网站网址是-python是什么语言

Python是一种面向对象的高级编程语言&#xff0c;具有集成的动态语义&#xff0c;主要用于Web和应用程序开发&#xff1b;它在快速应用程序开发领域极具吸引力&#xff0c;因为它提供动态类型和动态绑定选项。python是一种广泛使用的具有动态语义的解释型&#xff0c;面向对象的…

一个讲解WiFi和蓝牙协议的视频课程网站

以下是网站的地址&#xff0c;感觉还挺不错的&#xff0c;有深化的作用&#xff1b; https://www.bilibili.com/video/av63145588?p8 还有一个不错的通过8266来介绍当前WiFi模块所有应用的视频课程&#xff1a; https://www.bilibili.com/video/av75621470/?p2

python可以做网站吗-python怎么做网站

Python是一门简单易学的编程语言&#xff0c;代码简洁优美&#xff0c;最近&#xff0c;随着人工智能技术兴起&#xff0c;python也跟着火起来了。 想要用python搭建网站&#xff0c;就必须学会相应的Web开发框架&#xff0c;现在比较热门的web框架是Flask和Django&#xff0c;…

python bottle开发实例-用python web框架 bottle 开发网站(四)

在第三节我们熟悉并编写了用户登录逻辑&#xff0c;这一节我们要实现用户状态保持&#xff0c;就是判断用户当前的登录状态&#xff0c;我们用加密cookie的方式来实现&#xff0c;在bottle中用response.set_cookie()和requests.get_cookie()来写入和读取用户cookie&#xff0c;…

python、语言的主网站网址是-国产编程语言木兰被网友扒皮:原来是Python语言打包...

日前中科院计算所下属单位发布了编程语言木兰&#xff0c;号称计算所编译实验室完全自主设计、开发和实现的编程语言&#xff0c;与之配套的编译器与集成开发工具也完全由团队自主实现。不过该语言发布之后&#xff0c;网友发现它其实是Python语言打包的&#xff0c;很多函数都…

css 网站常用

简单的loading效果 .progressBar {border: solid 1px #303031; font: bold 20px/22px Arial, sans-serif;background: white url(/images/loading.gif) no-repeat 10px 10px; filter:alpha(opacity85); -moz-opacity:0.85; -khtml-opacity: 0.85; opacity: 0.85; }.progres…

电商网站滑动门特效

今天在慕课网学习了JavaScript滑动门特效&#xff0c;这个特效在电商网站上比较常见&#xff0c;难度适中&#xff0c;要对JavaScript和DOM比较熟悉。 一、实现HTML CSS结构 首先编写HTML代码 1 <!doctype html>2 <html>3 <head>4 <meta cha…

python写网站和java写网站的区别-为什么说Java和Python现阶段并不适合普通网站建设...

经过20多年的发展&#xff0c;网站开发技术已经非常成熟&#xff0c;用于网站制作的程序语言也有很多。常见的当然是php和asp.net&#xff0c;特别是php程序语言&#xff0c;虽然其已经有很多年历史也历经多次迭代升级&#xff0c;但在凭借其开源、轻巧等优势&#xff0c;在网站…

网站安全扫描工具--Netsparker的使用

Netsparker是一款安全简单的web应用安全漏电扫描工具。该软件功能非常强大&#xff0c;使用方便.Netsparker与其他综合 性的web应用安全扫描工具相比的一个特点是它能够更好的检测SQL Injection和 Cross-site Scripting类型的安全漏洞. 一 新建. 打开软件后,首先创建一个方案,…

自学python网站-分享干货:三个新手自学Python的网站!

廖雪峰博客 小白的Python新手教程&#xff0c;具有如下特点&#xff1a;中文&#xff0c;免费&#xff0c;零起点&#xff0c;完整示例&#xff0c;基于最新的Python 3版本。随着AI时代的来临&#xff0c;Python已经是必学语言。 哔哩哔哩视频 B站有很多Python教学&#xff0c;…

自学python网站-自学Python网站推荐 从入门到精通

Python作为可在任何平台上运行的通用语言&#xff0c;深受编程语言学习者的喜爱。那么究竟该如何自学Python呢&#xff1f;本文小编将推荐自学Python的网站——博学谷。博学谷是传智播客旗下IT在线教育品牌&#xff0c;面向各个学习能力不同阶段学员&#xff0c;在这个平台上大…

python中小学生编程学习-推荐几个适合小白学习Python的免费网站

9gd少儿编程网-Scratch_Python_教程_免费儿童编程学习平台 想要学好python&#xff0c;只靠看Python相关的书籍是远远不够的&#xff01;互联网时代&#xff0c;我们还要充分利用网络上的免费资源&#xff0c;不然怎样成为一名**的Pythoner呢&#xff1f;今天小U就为大家分享几…

为何python不好找工作编程-为何python不好找工作,seo行业不好转行了

为什么python不太好找个工作 一切正常买的这一結果得话&#xff0c;你吸气这一无法得到服务项目对吧&#xff1f;教师被不平稳啊&#xff0c;网站被黑呀无法打开呀对吧&#xff1f;这一切这一切都是你自身那时候想不到好做个哪些的都是中后期对吧&#xff1f;哎哟&#xff0c;她…

python工作岗位的个人优势-Python历史+优缺点+应用领域+网站职位简介

一、Python的历史 1. 1989年圣诞节&#xff1a;Guido von Rossum开始写Python语言的编译器。 2. 1991年2月&#xff1a;第一个Python编译器&#xff08;同时也是解释器&#xff09;诞生&#xff0c;它是用C语言实现的&#xff08;后面又出现了Java和C#实现的版本Jython和IronPy…

html table 样式_网站设计时更改HTML表格背景色的新方法探索

在网站建设开发中&#xff0c;表格几乎每个网站都会有所使用&#xff0c;而使用css样式表更改表格或者单元格背景颜色更不陌生。这篇文章讲述的主题&#xff0c;通过一些技术探索&#xff0c;告诉你在网站设计时更改HTML表格背景色的新方法。多年来&#xff0c;更改网站上表格各…

【PC工具】建议收藏!一个有N多日常生活学习办公小工具的神奇网站,推荐在线工具网站...

先发链接&#xff1a;http://www.gjw123.com/里边都是日常工作、生活、学习中可能会用到的&#xff0c;提高效率的小工具&#xff0c;很全面&#xff0c;比如&#xff1a;pdf格式转换、图片去水印、图片文字转换、logo制作等等。都是即点即用的&#xff0c;无需安装下载&#x…

【树莓派】可能是最简单粗暴的树莓派搭建个人网站教程

对很多初学者而言&#xff0c;在树莓派或服务器上搭建网站是一件非常头疼的事&#xff0c;不仅要在linux上运行命令行&#xff0c;还需要安装各种环境&#xff0c;稍微出点问题就可能前功尽弃。今天我给大家介绍一种简单粗暴无脑的网站搭建方法&#xff0c;全图形化鼠标操作&am…

生成元(Digit Generator ,ACM/ICPC Seoul 2005 ,UVa 1583)

生成元&#xff1a;如果 x 加上 x 各个数字之和得到y&#xff0c;则说x是y的生成元。 n&#xff08;1<n<100000&#xff09;,求最小生成元&#xff0c;无解输出0. 例如&#xff1a;n216 , 解是&#xff1a;198 198198216 解题思路&#xff1a;打表 循环将从1到10005&…

代码生成器,自己实现的一个基于模板的在线代码生成网站

说起为什么要做一个代码生成器&#xff0c;这个还是因为在做一个业务项目的时候&#xff0c;大量的页面功能要做&#xff0c;从后台到前台&#xff0c;虽然也选了一个基础的SSH框架系统做模板其结果还是耗费了大量的时间去一点一点的写代码&#xff0c;再加上业务需求并不明确&…

网站的容错性设计原则

互联网技术的飙升&#xff0c;网络技术的大量使用&#xff0c;郑州网站建设公司的职责也变得非常的高大上和沉重。如今市场上越来越多的B2C和C2C产品的用户体验越来越重要了&#xff0c;但是站在用户的角度上面&#xff0c;并不是每次搜索都是对的&#xff0c;我们在搜索浏览器…