├── .gitignore ├── 58gua_kao_factory.py ├── LICENSE ├── README.md ├── configs ├── 58gua_kao.json ├── char │ └── specific_chars.json ├── demo.json ├── icp.json └── jingdong.json ├── demo.py ├── icp_factory.py ├── jingdong_factory.py ├── model ├── __init__.py ├── captcha.py ├── capthafactory.py ├── char.py └── utils.py ├── output ├── 58gua_kao │ ├── 138-13049954.jpg │ ├── 153-4856-9254.jpg │ └── 155-0416-8055.jpg ├── demo │ ├── 圪趟照虎.jpg │ ├── 殓蜒细睿.jpg │ └── 通疝纽翻.jpg ├── icp │ ├── 6NJ6FU.jpg │ ├── 9NPVXP.jpg │ └── NU6RS6.jpg └── jingdong │ ├── 9nEL.jpg │ ├── DK67.jpg │ └── o55v.jpg └── resources ├── background ├── 2.jpg ├── 3.jpg └── color.jpg ├── corpus ├── common_chinese.txt ├── phrase.txt ├── text.csv └── top_level_chinese.txt ├── font ├── ALKATIP_Elipbe.ttf ├── ALKATIP_Elipbe_Tom.ttf ├── FZSTK.TTF ├── FranklinGothBookCTT.ttf ├── PingFang_A.ttf ├── STHUPO.TTF ├── STXINWEI.TTF ├── ZegoeUISemiBold-U_0.ttf ├── calibri.ttf ├── calibril.ttf ├── fangzheng.ttf ├── msyh.ttc ├── msyhbd.ttc ├── msyhl.ttc ├── segoeuisl.ttf └── youyuan.ttf └── markdown ├── 138-13049954.jpg ├── 58.gif ├── 6NJ6FU.jpg ├── 9nEL.jpg ├── icp.jpg ├── jd.jpg ├── jy_g.jpg ├── jy_o.jpg ├── 圪趟照虎.jpg ├── 殓蜒细睿.jpg └── 通疝纽翻.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /58gua_kao_factory.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | target captcha url: http://www.58guakao.com/user/487549.html 5 | """ 6 | import json 7 | import random 8 | 9 | from PIL import Image 10 | from PIL import ImageFilter 11 | 12 | from model.capthafactory import CaptchaFactory 13 | from model.utils import CaptchaUtils 14 | 15 | 16 | def char_custom_fn(single_char): 17 | # do something you wanted 18 | # return single_char.filter(ImageFilter.GaussianBlur) 19 | return single_char 20 | 21 | 22 | def bg_custom_fn(bg): 23 | # do something you wanted 24 | # return bg.filter(ImageFilter.GaussianBlur) 25 | return bg 26 | 27 | 28 | def generate_phone_number(idx=0): 29 | sec = [3, 5, 8] 30 | other = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 31 | s1, s2 = False, False 32 | if idx % 2 == 0: 33 | s1 = True 34 | if idx % 4 == 0: 35 | s2 = True 36 | 37 | res = "1" 38 | for i in range(2, 12): 39 | if i == 2: 40 | res += str(random.choice(sec)) 41 | elif i == 3: 42 | res += str(random.choice(other)) + "-" if s1 else str(random.choice(other)) 43 | elif i == 7 and s2: 44 | res += str(random.choice(other)) + "-" if s2 else str(random.choice(other)) 45 | else: 46 | res += str(random.choice(other)) 47 | 48 | return res 49 | 50 | 51 | def generate_mobile_number(idx=0): 52 | def generate_area_code(idx=0): 53 | lens = 3 + idx % 2 54 | return "0" + "".join([str(random.choice(range(0, 10))) for i in range(1, lens)]) 55 | 56 | res = "" 57 | if idx % 3 == 0: 58 | res += generate_area_code(idx) + "-" 59 | for i in range(8): 60 | res += str(random.choice(range(0, 10))) 61 | 62 | return res 63 | 64 | 65 | def main(): 66 | project_name = "58gua_kao" 67 | with open("configs/%s.json" % project_name, encoding="utf-8") as fp: 68 | demo_config = json.load(fp) 69 | 70 | demo_factory = CaptchaFactory(char_custom_fns=[char_custom_fn], bg_custom_fns=[bg_custom_fn], **demo_config) 71 | index = 3 72 | while index: 73 | # text = generate_phone_number(index) 74 | text = generate_mobile_number(index) 75 | 76 | captcha = demo_factory.generate_captcha(text=text) 77 | captcha.save("output/%s/%s.jpg" % (project_name, captcha.text)) 78 | print(captcha.text, captcha.num) 79 | 80 | index -= 1 81 | 82 | 83 | if __name__ == "__main__": 84 | main() 85 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # any-captcha 2 | generate any type of captcha with one config. 3 | 一套配置,一行代码,快速生成任意风格验证码。 4 | 5 | ## 功能简述 6 | 通过简单的配置,可以快速生成大部分类型的验证码,旨在解决机器学习训练样本难以获取的问题,几乎可以0成本获取样本。 7 | 同时易于保存和修改,便于多次测试寻求最佳训练样本参数。更可以获取字符在验证码中的位置信息,适用于定位方面的项目。 8 | 温馨提示:搭配以下在线工具使用效率更佳: 9 | * 字体查找:http://www.qiuziti.com/ 10 | * 颜色查找:http://tools.jb51.net/color/colorpicker 11 | 12 | ## 目录结构 13 | any-captcha 14 | > configs: 存放配置文件 15 | > model: 项目源码 16 | > output: 默认验证码保存目录 17 | > resources 18 | >> background: 默认背景图片目录 19 | >> corpus: 默认字符文本目录 20 | >> font: 默认字体目录 21 | >> markdown: md需要的资源 22 | 23 | ## CONFIG参数说明 24 | * texts: 字符串数组,验证码上可显示的所有字符的集合,如果: 25 | 1. 数组长度大于1,每个元素能且只能是普通字符串(非文件和文件夹路径),且每个元素作为整体随机的显示在验证码中, 26 | 此时num参数失效,每张验证码的字符个数由当前元素长度决定; 27 | 2. 数组长度等于1,此元素可以是: 28 | * 文件路径:将文件中的每一行作为一个元素存储到数组中,然后按照1.处理; 29 | * 普通字符串:则随机选取num个字符显示在每个验证码中。 30 | *注:暂不支持文件夹路径。 31 | 32 | * fonts: 字符串数组,验证码字体文件(.ttf或.ttc,不区分大小写)路径的集合,如果: 33 | 1. 数组长度大于1,每个元素能且只能是字体文件的路径; 34 | 2. 数组长度等于1,此元素可以是单个字体文件的路径,或者存放字体的文件夹路径。 35 | 36 | * sizes: 整型数组,验证码中字号大小的集合。 37 | 38 | 39 | * bgs: 字符串数组,验证码的背景图片或者颜色的集合,如果: 40 | 1. 数组长度大于1,每个元素可以是【单张背景图片路径,单个背景颜色(格式同colors参数)】 41 | 中的一个; 42 | 2. 数组长度等于1,此元素可以是【单张背景图片路径,单个背景颜色,存放多张背景图片的文件夹路径, 43 | 存放多个背景颜色值的txt文件路径(每行一个颜色值)】中的一个; 44 | 45 | * rotate: 整型,验证码中单个字符可旋转角度的值,旋转角度的范围[-rotate, 46 | rotate],每次随机取值。 47 | 48 | * num: 整型, 验证码显示的字符个数,具体参见texts参数。 49 | 50 | * dot: 整型,验证码中随机噪点的个数,默认(0)不显示噪点,如果有特定噪点需求, 51 | 推荐使用CaptchaFactory中的bg_custom_fns参数自定义。 52 | 53 | * curve: 整型,验证码中随机干扰线的个数,默认(0)不显示干扰线,如有特殊需求同dot。 54 | 55 | * width: 整型,验证码的宽度。 56 | 57 | * height: 整型,验证码的高度。 58 | 59 | * align: 整型,验证码的对齐方式,取值1或2, 其中1为左对齐,2为两端对齐。 60 | 61 | * offset_ver: 整型,验证码中单个字符的垂直偏移量,默认(0)垂直居中,如果 62 | offset_ver > 0, 随机从[-offset_ver, offset_ver]中选取一个偏移量。 63 | 64 | * offset_hor: 整型,验证码中单个字符的水平偏移量,默认(0)与前一个相接,如果 65 | offset_hor > 0, 随机从[-offset_hor, offset_hor]中选取一个偏移量。 66 | 67 | * char_tran: 浮点型数组,验证码中字符可选的透明度集合,单个元素取值范围[0.0,100.0]。 68 | 69 |

*注:以上参数都可以被CaptchaFactory.generate_captcha()方法中的相关参数覆盖,即可以动态指 70 | 定每一个参数。

71 | 72 | 73 | ## 样例代码 74 | 75 | ### config: 76 | ```json 77 | { 78 | "texts": [ 79 | "resources/corpus/common_chinese.txt" 80 | ], 81 | "fonts": [ 82 | "resources/font/PingFang_A.ttf", 83 | "resources/font/STXINWEI.TTF" 84 | ], 85 | "sizes": [ 86 | 38,40,42 87 | ], 88 | "colors": [ 89 | "0x32678b", 90 | "0xe61514", 91 | "0x3e0ac3" 92 | ], 93 | "bgs": [ 94 | "0xfef6f6", 95 | "resources/background/color.jpg" 96 | ], 97 | "rotate": 30, 98 | "num": 4, 99 | "dot": 0, 100 | "curve": 0, 101 | "width": 200, 102 | "height": 60, 103 | "align": 2, 104 | "offset_ver": 5, 105 | "offset_hor": 6, 106 | "char_tran": [ 107 | 5.97 108 | ] 109 | } 110 | ``` 111 | ### main code: 112 | ```python 113 | def main(): 114 | project_name = "demo" 115 | with open("configs/%s.json" % project_name, encoding="utf-8") as fp: 116 | demo_config = json.load(fp) 117 | 118 | demo_factory = CaptchaFactory(**demo_config) 119 | index = 3 120 | while index: 121 | captcha = demo_factory.generate_captcha() 122 | captcha.save("output/%s/%s.jpg" % (project_name, captcha.text)) 123 | print(captcha.text, captcha.num) 124 | 125 | index -= 1 126 | ``` 127 | ### 输出: 128 | * ![圪趟照虎](resources/markdown/圪趟照虎.jpg) 129 | * ![殓蜒细睿](resources/markdown/殓蜒细睿.jpg) 130 | 131 | 其他完整样例见58gua_kao_factory.pyicp_factory.pyjingdong_factory.py. 132 | 133 | ## 效果比对 134 | 135 | 原始验证码 | 生成验证码 136 | | :-----: | :-----: | 137 | | ![jd_o](resources/markdown/jd.jpg) | ![jd_g](resources/markdown/9nEL.jpg) | 138 | | ![58_o](resources/markdown/58.gif) | ![58_g](resources/markdown/138-13049954.jpg) | 139 | | ![icp_o](resources/markdown/icp.jpg) | ![icp_g](resources/markdown/6NJ6FU.jpg) | 140 | | ![jd_o](resources/markdown/jy_o.jpg) | ![jd_g](resources/markdown/jy_g.jpg) | 141 | 142 | ## 高级功能 143 | ### 自定义噪点/干扰线 144 | 此项目只提供了简单生成随机噪点或干扰先的方法,如有需要,可以通过简单配置config中dot或 145 | curve生成。但更多时候,验证码中的干扰线和噪点都是需要自定义的,所以在 146 | CaptchaFactory的构造方法中提供了以下两个参数,用于接收相关的回调函数: 147 | * char_custom_fns:如果对于单个字符有其他自定义操作,比如拉伸形变、膨胀腐蚀等, 148 | 可以通过此参数传入回调函数,支持多个回调函数随机调用。 149 | ```python 150 | def char_custom_fn(single_char): 151 | # do something you wanted 152 | # return single_char.filter(ImageFilter.GaussianBlur) 153 | return single_char 154 | ``` 155 | * bg_custom_fns:如果对于验证码背景有其他自定义操作,比如高斯模糊、指定样式的噪点或干扰线等, 156 | 可以通过此参数传入回调函数,支持多个回调函数随机调用。 157 | ```python 158 | def bg_custom_fn(bg): 159 | # do something you wanted 160 | # return bg.filter(ImageFilter.GaussianBlur) 161 | return bg 162 | ``` 163 | 详细代码见jingdong_factory.py. 164 | ### 字符位置: 165 | 可以通过Captcha.char_pos()方法获取单个字符在验证码中的位置信息,返回一个四元组(x,y,w,h), 166 | 分别表示左上角x坐标,y坐标,宽,高,适用于物体检测,文字定位等问题,配合YOLO使用。 167 | 样例: 168 | ```python 169 | captcha = demo_factory.generate_captcha() 170 | char_pos = captcha.char_pos 171 | width = captcha.width 172 | height = captcha.height 173 | with open(os.path.join(output_path, txt_out), "w", encoding="utf-8") as fp: 174 | for pos in char_pos: 175 | x, y, w, h = pos 176 | # 转化为中心点的坐标 177 | # x = (x + w / 2) * 1.0 / width 178 | # y = (y + h / 2) * 1.0 / height 179 | ``` 180 | ## TODO 181 | * 新增配置项char_times:保证语料库中每个字符至少出现char_times次 182 | * 配置项的颜色格式改为:#ffffff 183 | * 新增分析原始验证码中前景背景色分布的功能 184 | * 支持多线程生成验证码 185 | * 新增常用图像处理方法(增强,扭曲等) 186 | * 判断自生成验证码和原始验证码的相似度 187 | 188 | -------------------------------------------------------------------------------- /configs/58gua_kao.json: -------------------------------------------------------------------------------- 1 | { 2 | "texts": [ 3 | "0123456789" 4 | ], 5 | "fonts": [ 6 | "resources/font/CalibriL.ttf" 7 | ], 8 | "sizes": [ 9 | 28 10 | ], 11 | "colors": [ 12 | "0xff0000" 13 | ], 14 | "bgs": [ 15 | "0xfef6f6", 16 | "0xfefdf9" 17 | ], 18 | "rotate": 0, 19 | "num": 11, 20 | "dot": 0, 21 | "curve": 0, 22 | "width": 167, 23 | "height": 35, 24 | "align": 1, 25 | "offset_ver": 0, 26 | "offset_hor": 0, 27 | "char_tran": [ 28 | 5.97 29 | ] 30 | } -------------------------------------------------------------------------------- /configs/char/specific_chars.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "char": "拉", 4 | "font": "resources/font/STCAIYUN.TTF", 5 | "size": 50, 6 | "color": "0x184830", 7 | "rotate": -15, 8 | "position_x": 30, 9 | "position_y": 130 10 | }, 11 | { 12 | "char": "枯", 13 | "font": "resources/font/STCAIYUN.TTF", 14 | "size": 50, 15 | "color": "0x184830", 16 | "rotate": -30, 17 | "position_x": 40, 18 | "position_y": 330, 19 | "char_tran": "", 20 | "fn": "" 21 | }, 22 | { 23 | "char": "折", 24 | "font": "resources/font/STCAIYUN.TTF", 25 | "size": 50, 26 | "color": "0xeeeeee", 27 | "rotate": 6, 28 | "position_x": 30, 29 | "position_y": 210, 30 | "custom_fn": "" 31 | }, 32 | { 33 | "char": "朽", 34 | "font": "resources/font/STCAIYUN.TTF", 35 | "size": 50, 36 | "color": "0x184830", 37 | "rotate": -30, 38 | "position_x": 170, 39 | "position_y": 30 40 | } 41 | ] -------------------------------------------------------------------------------- /configs/demo.json: -------------------------------------------------------------------------------- 1 | { 2 | "texts": [ 3 | "resources/corpus/common_chinese.txt" 4 | ], 5 | "fonts": [ 6 | "resources/font/PingFang_A.ttf", 7 | "resources/font/STXINWEI.TTF" 8 | ], 9 | "sizes": [ 10 | 38,40,42 11 | ], 12 | "colors": [ 13 | "0x32678b", 14 | "0xe61514", 15 | "0x3e0ac3" 16 | ], 17 | "bgs": [ 18 | "0xfef6f6", 19 | "resources/background/color.jpg" 20 | ], 21 | "rotate": 30, 22 | "num": 4, 23 | "dot": 0, 24 | "curve": 0, 25 | "width": 200, 26 | "height": 60, 27 | "align": 2, 28 | "offset_ver": 5, 29 | "offset_hor": 6, 30 | "char_tran": [ 31 | 5.97 32 | ] 33 | } -------------------------------------------------------------------------------- /configs/icp.json: -------------------------------------------------------------------------------- 1 | { 2 | "texts": [ 3 | "ABCDEFGHIJKLMNOPORSTUVWXYZ0123456789" 4 | ], 5 | "fonts": [ 6 | "resources/font/ALKATIP_Elipbe_Tom.ttf" 7 | ], 8 | "sizes": [ 9 | 38, 10 | 40, 11 | 42 12 | ], 13 | "colors": [ 14 | "0x301878", 15 | "0x184830", 16 | "0x606030", 17 | "0x603018", 18 | "0x601878", 19 | "0x303078", 20 | "0x303030", 21 | "0x186018", 22 | "0x303090", 23 | "0x304860", 24 | "0x306048", 25 | "0x304848", 26 | "0x481860", 27 | "0x181818", 28 | "0x186030", 29 | "0x606048", 30 | "0x181848", 31 | "0x487818", 32 | "0x607830" 33 | ], 34 | "bgs": [ 35 | "0xF0D8F0", 36 | "0xF0D8FF", 37 | "0xC0F0D8", 38 | "0xF0F0C0", 39 | "0xD8F0C0", 40 | "0xD8C0F0", 41 | "0xD8C0D8", 42 | "0xC0D8C0", 43 | "0xF0D8D8", 44 | "0xF0C0C0", 45 | "0xC0C0F0", 46 | "0xD8D8FF" 47 | ], 48 | "rotate": 20, 49 | "num": 6, 50 | "dot": 0, 51 | "curve": 4, 52 | "width": 200, 53 | "height": 60, 54 | "align": 2, 55 | "offset_ver": 10, 56 | "offset_hor": 8, 57 | "outline_color": "" 58 | } -------------------------------------------------------------------------------- /configs/jingdong.json: -------------------------------------------------------------------------------- 1 | { 2 | "texts": [ 3 | "abcdefjhigklmnporstuvwxyzABCDEFGHIJKLMNPORSTUVWXYZ123456789" 4 | ], 5 | "fonts": [ 6 | "resources/jingdong_font/ALKATIP_Elipbe.ttf" 7 | ], 8 | "sizes": [ 9 | 24, 10 | 26 11 | ], 12 | "colors": [ 13 | "0x301878", 14 | "0x184830", 15 | "0x606030", 16 | "0x891c39", 17 | "0x603018", 18 | "0x601878", 19 | "0x303078", 20 | "0x186018", 21 | "0x303090", 22 | "0x304860", 23 | "0x306048", 24 | "0x304848", 25 | "0x481860", 26 | "0x186030", 27 | "0x181848", 28 | "0x487818" 29 | ], 30 | "bgs": [ 31 | "0xfef6f6", 32 | "0xfefdf9" 33 | ], 34 | "rotate": 10, 35 | "num": 4, 36 | "dot": 0, 37 | "curve": 0, 38 | "width": 85, 39 | "height": 26, 40 | "align": 2, 41 | "offset_ver": 5, 42 | "offset_hor": 4, 43 | "char_tran": [ 44 | 5.97, 45 | 3.14, 46 | 9 47 | ] 48 | } -------------------------------------------------------------------------------- /demo.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | import json 4 | import random 5 | 6 | from PIL import Image 7 | from PIL import ImageFilter 8 | 9 | from model.capthafactory import CaptchaFactory 10 | from model.utils import CaptchaUtils 11 | 12 | 13 | def char_custom_fn(single_char): 14 | # do something you wanted 15 | # return single_char.filter(ImageFilter.GaussianBlur) 16 | return single_char 17 | 18 | 19 | def bg_custom_fn(bg): 20 | # do something you wanted 21 | # return bg.filter(ImageFilter.GaussianBlur) 22 | return bg 23 | 24 | 25 | def main(): 26 | project_name = "demo" 27 | with open("configs/%s.json" % project_name, encoding="utf-8") as fp: 28 | demo_config = json.load(fp) 29 | 30 | demo_factory = CaptchaFactory(char_custom_fns=[char_custom_fn], bg_custom_fns=[bg_custom_fn], **demo_config) 31 | index = 3 32 | while index: 33 | captcha = demo_factory.generate_captcha() 34 | captcha.save("output/%s/%s.jpg" % (project_name, captcha.text)) 35 | print(captcha.text, captcha.num) 36 | 37 | index -= 1 38 | 39 | 40 | if __name__ == "__main__": 41 | main() 42 | -------------------------------------------------------------------------------- /icp_factory.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | target captcha url: http://www.miitbeian.gov.cn/getVerifyCode?4 5 | """ 6 | import json 7 | 8 | from model.capthafactory import CaptchaFactory 9 | 10 | 11 | def custom_fn(single_char): 12 | # do something 13 | # return single_char.filter(ImageFilter.GaussianBlur) 14 | return single_char 15 | 16 | 17 | def bg_custom_fn(bg): 18 | # do something 19 | # return bg.filter(ImageFilter.GaussianBlur) 20 | return bg 21 | 22 | 23 | def main(): 24 | project_name = "icp" 25 | with open("configs/icp.json", encoding="utf-8") as fp: 26 | demo_config = json.load(fp) 27 | 28 | # with open("configs/char/specific_chars.json", encoding="utf-8") as fp: 29 | # specific = json.load(fp) 30 | 31 | demo_factory = CaptchaFactory(char_custom_fns=[custom_fn], bg_custom_fns=[bg_custom_fn], **demo_config) 32 | number = 3 33 | while number: 34 | # captcha = demo_factory.generate_captcha(specific_chars=specific) 35 | captcha = demo_factory.generate_captcha() 36 | captcha.save("output/%s/%s.jpg" % (project_name, captcha.text)) 37 | print(captcha.text, captcha.num) 38 | 39 | number -= 1 40 | 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /jingdong_factory.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | import json 3 | import sys 4 | 5 | sys.path.append("..") 6 | from PIL import Image 7 | from PIL import ImageFilter 8 | 9 | from model.capthafactory import CaptchaFactory 10 | from model.utils import CaptchaUtils 11 | 12 | 13 | def custom_fn(single_char): 14 | # do something you wanted 15 | # return single_char.filter(ImageFilter.GaussianBlur) 16 | return single_char 17 | 18 | 19 | def bg_custom_fn(bg): 20 | # do something you wanted 21 | # return bg.filter(ImageFilter.GaussianBlur) 22 | CaptchaUtils.draw_line(bg, (0, CaptchaUtils.random_choice_from(range(12, 14))), 23 | (85, CaptchaUtils.random_choice_from(range(13, 15))), 24 | CaptchaUtils.get_rgb("0x595e12"), 1) 25 | CaptchaUtils.draw_line(bg, (0, CaptchaUtils.random_choice_from(range(11, 16))), 26 | (85, CaptchaUtils.random_choice_from(range(17, 21))), CaptchaUtils.get_rgb("0x563c7c"), 1) 27 | return bg 28 | 29 | 30 | def main(): 31 | project_name = "jingdong" 32 | with open("configs/%s.json" % project_name, encoding="utf-8") as fp: 33 | demo_config = json.load(fp) 34 | 35 | demo_factory = CaptchaFactory(char_custom_fns=[custom_fn], bg_custom_fns=[bg_custom_fn], **demo_config) 36 | number = 3 37 | while number: 38 | # captcha = demo_factory.generate_captcha(specific_chars=specific) 39 | captcha = demo_factory.generate_captcha() 40 | captcha.save("output/%s/%s.jpg" % (project_name, captcha.text)) 41 | # for c in captcha.chars: 42 | # print(c.char_text, c.color) 43 | print(captcha.text, captcha.num) 44 | 45 | number -= 1 46 | 47 | 48 | if __name__ == "__main__": 49 | main() 50 | -------------------------------------------------------------------------------- /model/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/model/__init__.py -------------------------------------------------------------------------------- /model/captcha.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | import os 3 | import random 4 | 5 | import re 6 | from PIL import Image 7 | from PIL.ImageDraw import Draw 8 | from model.utils import CaptchaUtils 9 | from model.char import Char 10 | 11 | 12 | class Captcha(object): 13 | def __init__(self, text, bg, char_custom_fns=None, bg_custom_fn=None, specific_chars=None, **kwargs): 14 | self._kwargs = kwargs 15 | # 验证码上显示的文本内容 16 | self._text = text 17 | # 验证码的背景,图片路径或者颜色字符串(e.g.:0xffffff) 18 | self._background = bg 19 | # 验证码文本长度 20 | self._num = len(self._text) 21 | # 验证码中所有的字符对象, [anycaptcha.char.Char] 类型 22 | self._chars = [] 23 | # 验证码中所有的字符的位置信息,4-tuple(e.g.(0,0,25,30)),分别表示左上角点x坐标,y坐标,宽,高 24 | self._char_pos = [] 25 | 26 | # 验证码背景处理的自定义函数 27 | self._bg_custom_fn = bg_custom_fn 28 | 29 | # 验证码指定字符的详细信息,相关配置参见"configs/char/specific_chars.json" 30 | self._specific_chars = specific_chars 31 | 32 | # 验证码噪点的个数 33 | self._dot = self._kwargs.get("dot", 0) 34 | 35 | # 验证码干扰线的个数 36 | self._curve = self._kwargs.get("curve", 0) 37 | 38 | # 验证码的宽 39 | self._width = self._kwargs.get("width", 60) 40 | 41 | # 验证码的高 42 | self._height = self._kwargs.get("height", 200) 43 | 44 | # 验证码中单个字符对象的垂直偏移量,默认(0)垂直居中,if > 0, 随机从(-_off_ver,_off_ver)中选取一个 45 | self._off_ver = self._kwargs.get("offset_ver", 0) 46 | 47 | # 验证码中单个字符对象的水平偏移量,默认(0)紧跟上个字符,if > 0, 随机从(-_off_hor,_off_hor)中选取一个 48 | self._off_hor = self._kwargs.get("offset_hor", 0) 49 | 50 | # 验证码中单个字符对象的轮廓线的颜色,如果为空,则不显示 51 | self._outline_color = self._kwargs.get("outline_color", None) 52 | 53 | # 验证码中字符的对齐方式,1:左对齐;2:两端对齐 54 | self._align = self._kwargs.get("align", 2) 55 | 56 | # 验证码中字符可选的字体集合 57 | self._char_fonts = self._kwargs.get("fonts", ["consola.ttf"]) 58 | # 验证码中字符可选的字体大小集合 59 | self._char_sizes = self._kwargs.get("sizes", [38, 40, 42]) 60 | # 验证码中字符可选的字体颜色集合 61 | self._char_colors = self._kwargs.get("colors", ["0xffffff"]) 62 | # 验证码中字符可选的旋转角度集合(-_char_rotate,_char_rotate) 63 | self._char_rotate = self._kwargs.get("rotate", 0) 64 | # 验证码中字符可选的透明度集合(0-100) 65 | self._char_tran = self._kwargs.get("char_tran", [5.97]) 66 | # 验证码处理单个字符的自定义函数集合 67 | self._char_custom_fns = char_custom_fns 68 | 69 | self._captcha = None 70 | self.init_font() 71 | self._captcha = self.captcha 72 | 73 | def init_font_size(self): 74 | CaptchaUtils.random_choice_from(self._char_sizes) 75 | 76 | def init_captcha(self): 77 | tmp_captcha = None 78 | if os.path.isfile(self._background): 79 | tmp_captcha = Image.open(self._background).resize((self._width, self._height)) 80 | else: 81 | bg = CaptchaUtils.get_rgb(self._background) 82 | tmp_captcha = Image.new('RGB', (self._width, self._height), bg) 83 | 84 | if self._bg_custom_fn: 85 | tmp_captcha = self._bg_custom_fn(tmp_captcha) 86 | 87 | return tmp_captcha 88 | 89 | def init_font(self): 90 | if len(self._char_fonts) == 1: 91 | unknown_string = self._char_fonts[0] 92 | if os.path.isdir(unknown_string): 93 | files = os.listdir(unknown_string) 94 | 95 | self._char_fonts = [os.path.join(unknown_string, file) for file in files if 96 | file.lower().endswith(".ttf") or file.lower().endswith(".ttc")] 97 | 98 | for _char_font in self._char_fonts: 99 | if not os.path.isfile(_char_font): 100 | raise FileNotFoundError("this font connot be found. font path:%s" % _char_font) 101 | 102 | def select_rotate(self): 103 | rotate = random.uniform(-self._char_rotate, self._char_rotate) 104 | 105 | return rotate 106 | 107 | def select_char_custom_fns(self): 108 | fn = None 109 | if self._char_custom_fns: 110 | fn = CaptchaUtils.random_choice_from(self._char_custom_fns) 111 | 112 | return fn 113 | 114 | def select_font(self): 115 | font = CaptchaUtils.random_choice_from(self._char_fonts) 116 | 117 | return font 118 | 119 | def select_size(self): 120 | size = CaptchaUtils.random_choice_from(self._char_sizes) 121 | 122 | return size 123 | 124 | def select_char_tran(self): 125 | char_tran = CaptchaUtils.random_choice_from(self._char_tran) 126 | 127 | return char_tran 128 | 129 | def select_color(self): 130 | color = CaptchaUtils.random_choice_from(self._char_colors) 131 | 132 | return color 133 | 134 | def draw_noise_dot(self, color="0x484848", width=3, number=30): 135 | while number: 136 | CaptchaUtils.draw_dot(self._captcha, color=CaptchaUtils.get_rgb(color), width=width) 137 | number -= 1 138 | 139 | def draw_noise_curve(self, color="0x484848", number=4, width=3, type="line"): 140 | points = [CaptchaUtils.random_point(self._width, self._height) for i in range(number + 1)] 141 | if type == "line": 142 | for idx in range(len(points) - 1): 143 | CaptchaUtils.draw_line(self._captcha, points[idx], points[idx + 1], CaptchaUtils.get_rgb(color), width) 144 | elif type == "curve": 145 | pass 146 | # CaptchaUtils.draw_curve() 147 | else: 148 | pass 149 | 150 | def get_actual_x(self, except_x, im_width): 151 | act = except_x + random.randint(-self._off_hor, self._off_hor) 152 | 153 | if act + im_width > self._width - 2: 154 | return self._width - im_width - 2 155 | elif act < 2: 156 | return 2 157 | else: 158 | return act 159 | 160 | def get_actual_y(self, except_y, h): 161 | act = except_y + random.randint(-self._off_ver, self._off_ver) 162 | 163 | if act + h > self._height - 2: 164 | return self._height - h - 2 165 | elif act < 2: 166 | return 2 167 | else: 168 | return act 169 | 170 | def joint_image(self): 171 | average = int(self._width / self._num) 172 | except_x = 0 173 | 174 | for char in self._chars: 175 | _char = char.char 176 | # _char.show() 177 | w, h = _char.size 178 | except_y = int((self._height - h) / 2) 179 | 180 | if char.position_x is None: 181 | char.set_x(self.get_actual_x(except_x, w)) 182 | if char.position_y is None: 183 | char.set_y(self.get_actual_y(except_y, h)) 184 | 185 | self._captcha.paste(_char, (char.position_x, char.position_y), char.mask) 186 | # self._captcha.show() 187 | self._char_pos.append((char.position_x, char.position_y, w, h)) 188 | 189 | if self._outline_color: 190 | color = CaptchaUtils.get_rgb(self._outline_color) 191 | self.draw_outline(char.position_x, char.position_y, w, h, color) 192 | # 左对齐 193 | if self._align == 1: 194 | except_x += _char.width 195 | else: # 两端对齐 196 | except_x += average 197 | 198 | def draw_outline(self, actual_x, actual_y, w, h, color): 199 | CaptchaUtils.draw_rectangle(self._captcha, (actual_x, actual_y, w, h), color) 200 | 201 | def create_captcha(self): 202 | specific = [{}] * self._num 203 | if self._specific_chars: 204 | specific = self._specific_chars 205 | [specific.append({}) for i in range(self._num - len(specific)) if self._num - len(specific) > 0] 206 | act_text = [] 207 | for i in range(self._num): 208 | draw = Draw(self._captcha) 209 | char = specific[i].get("char", self._text[i]) 210 | color = specific[i].get("color", self.select_color()) 211 | font = specific[i].get("font", self.select_font()) 212 | size = specific[i].get("size", self.select_size()) 213 | rotate = specific[i].get("rotate", self.select_rotate()) 214 | x = specific[i].get("position_x", None) 215 | y = specific[i].get("position_y", None) 216 | fn = specific[i].get("fn", self.select_char_custom_fns()) 217 | char_tran = specific[i].get("char_tran", self.select_char_tran()) 218 | self._chars.append(Char(char=char, color=color, font=font, size=size, draw=draw, 219 | rotate=rotate, position_x=x, position_y=y, char_tran=char_tran, custom_fn=fn)) 220 | 221 | act_text.append(char) 222 | 223 | if len(specific) > self._num: 224 | for i in range(self._num, len(specific)): 225 | act_text.append(specific[i].get("char", "A")) 226 | self._chars.append(Char(draw=Draw(self._captcha), **specific[i])) 227 | self._num += 1 228 | 229 | self._text = "".join(act_text) 230 | self.joint_image() 231 | 232 | if self._curve: 233 | self.draw_noise_curve(number=self._curve) 234 | if self._dot: 235 | self.draw_noise_dot(number=self._dot) 236 | 237 | def save(self, fp): 238 | lens = self._captcha.split() 239 | path = re.findall("(.+/).+", fp)[0] 240 | if os.path.exists(path) is False: 241 | os.makedirs(path) 242 | 243 | if fp.lower().endswith("jpg") and len(lens) == 4: 244 | r, g, b, a = lens 245 | tmp = Image.merge("RGB", (r, g, b)) 246 | tmp.save(fp, "JPEG") 247 | else: 248 | self._captcha.save(fp) 249 | 250 | def show(self): 251 | self._captcha.show() 252 | 253 | @property 254 | def captcha(self): 255 | if self._captcha is None: 256 | self._captcha = self.init_captcha() 257 | self.create_captcha() 258 | 259 | return self._captcha 260 | 261 | @property 262 | def chars(self): 263 | return self._chars 264 | 265 | @property 266 | def width(self): 267 | return self._width 268 | 269 | @property 270 | def height(self): 271 | return self._height 272 | 273 | @property 274 | def char_pos(self): 275 | return self._char_pos 276 | 277 | @property 278 | def background(self): 279 | return self._background 280 | 281 | @property 282 | def text(self): 283 | return self._text 284 | 285 | @property 286 | def num(self): 287 | return self._num 288 | -------------------------------------------------------------------------------- /model/capthafactory.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | import os 3 | 4 | from model.utils import CaptchaUtils 5 | 6 | from model.captcha import Captcha 7 | 8 | 9 | class CaptchaFactory(object): 10 | def __init__(self, char_custom_fns=None, bg_custom_fns=None, **kwargs): 11 | self._kwargs = kwargs 12 | self._char_custom_fns = char_custom_fns 13 | self._bg_custom_fns = bg_custom_fns 14 | self._num = self._kwargs.get("num", 4) 15 | self._texts = self._kwargs.get("texts", ["yangrui"]) 16 | self._bgs = self._kwargs.get("bgs", ["0xffffff"]) 17 | 18 | self.init() 19 | 20 | def init(self): 21 | self.init_text() 22 | self.init_background() 23 | 24 | def init_text(self): 25 | if len(self._texts) == 1: 26 | unknown_string = self._texts[0] 27 | if os.path.isfile(unknown_string): 28 | with open(unknown_string, encoding="utf-8") as fp: 29 | self._texts = fp.readlines() 30 | 31 | def init_background(self): 32 | # 如果长度为1,须判断是文件,路径还是颜色字符串 33 | if len(self._bgs) == 1: 34 | unknown_string = self._bgs[0] 35 | if os.path.isfile(unknown_string): # unknown_string.lower().endswith(".csv") 36 | # 如果是文件,则默认文件中的内容为颜色字符串,一行一个 37 | with open(unknown_string) as fp: 38 | self._bgs = fp.readlines() 39 | elif os.path.isdir(unknown_string): 40 | # 如果是路径,则默认路径中的每个文件都是一张图片 41 | files = os.listdir(unknown_string) 42 | self._bgs = [os.path.join(unknown_string, file) for file in files if 43 | file.lower().endswith(".jpg") or file.lower().endswith(".png")] 44 | 45 | def select_background(self): 46 | bg = CaptchaUtils.random_choice_from(self._bgs) 47 | return bg 48 | 49 | def select_bg_custom_fn(self): 50 | fn = None 51 | if self._bg_custom_fns: 52 | fn = CaptchaUtils.random_choice_from(self._bg_custom_fns) 53 | 54 | return fn 55 | 56 | def select_text(self): 57 | if len(self._texts) == 1: 58 | # 经过init_text后,如果还是只有一个元素,则认为这个元素就是可显示在验证中所有字符的集合 59 | return ''.join([CaptchaUtils.random_choice_from(self._texts[0]) for i in range(self._num)]) 60 | elif len(self._texts) > 1: 61 | # 否则,每个元素对应一张验证码的内容 62 | return CaptchaUtils.random_choice_from(self._texts).strip("\n") 63 | 64 | def generate_captcha(self, text=None, bg=None, bg_custom_fn=None, specific_chars=None): 65 | text = text or self.select_text() 66 | bg = bg or self.select_background() 67 | bg_custom_fn = bg_custom_fn or self.select_bg_custom_fn() 68 | return Captcha(text=text, bg=bg, char_custom_fns=self._char_custom_fns, 69 | bg_custom_fn=bg_custom_fn, specific_chars=specific_chars, **self._kwargs) 70 | 71 | # def generate_captcha(self): 72 | # text = self.select_text() 73 | # bg = self.select_background() 74 | # return Captcha(text, bg, **self._kwargs) 75 | -------------------------------------------------------------------------------- /model/char.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from PIL import Image 4 | from PIL.ImageDraw import Draw 5 | from PIL.ImageFont import truetype 6 | 7 | from model.utils import CaptchaUtils 8 | 9 | 10 | class Char(object): 11 | def __init__(self, char='A', color="0x000000", font="consola.ttf", size=40, draw=None, 12 | rotate=0, position_x=None, position_y=None, char_tran=5.97, custom_fn=None): 13 | # 字符的文字 14 | self._char_text = char 15 | # 字符的颜色 16 | self._color = color 17 | # 字符的字体 18 | self._font = font 19 | # 字符字体的大小 20 | self._fsize = size 21 | self._draw = draw 22 | # 字符的宽度,根据字符图片旋转,自定义处理后自动算出,不要手动设置 23 | self._width = None 24 | # 字符的高度,根据字符图片旋转,自定义处理后自动算出,不要手动设置 25 | self._height = None 26 | # 字符在背景图中的x坐标 27 | self._position_x = position_x 28 | # 字符在背景图中的y坐标 29 | self._position_y = position_y 30 | # 字符的旋转角度 31 | self._rotate = rotate 32 | # 字符的自定义函数 33 | self._custom_fn = custom_fn 34 | # 字符的图片对象 35 | self._char_image = None 36 | self._char_image = self.char 37 | # 字符的图片透明度 38 | self._char_tran = char_tran 39 | self._table = [] 40 | self._table = self.table 41 | self._mask = self._char_image.convert('L').point(self.table) 42 | 43 | @property 44 | def table(self): 45 | if self._table: 46 | return self._table 47 | else: 48 | for i in range(256): 49 | self._table.append(i * self._char_tran) 50 | return self._table 51 | 52 | def generate_true_font(self): 53 | return truetype(self._font, self._fsize) 54 | 55 | def create_character(self): 56 | font = self.generate_true_font() 57 | w, h = self._draw.textsize(self._char_text, font=font) 58 | 59 | self._char_image = Image.new('RGB', (w, h), 0) # (255, 255, 255) 60 | color = CaptchaUtils.get_rgb(self._color) 61 | Draw(self._char_image).text((0, 0), self._char_text, font=font, fill=color) 62 | # self._char_image.show() 63 | self._char_image = self._char_image.rotate(self._rotate, Image.BILINEAR, expand=1) 64 | self._char_image = self._char_image.crop(self._char_image.getbbox()) 65 | if self._custom_fn: 66 | tmp = self._char_image 67 | self._char_image = self._custom_fn(tmp) 68 | self._char_image = self._char_image.crop(self._char_image.getbbox()) 69 | 70 | self._width = self._char_image.size[0] 71 | self._height = self._char_image.size[1] 72 | 73 | @property 74 | def char(self): 75 | if self._char_image is None: 76 | self.create_character() 77 | 78 | return self._char_image 79 | 80 | @property 81 | def font(self): 82 | return self._font 83 | 84 | @property 85 | def char_text(self): 86 | return self._char_text 87 | 88 | @property 89 | def color(self): 90 | return self._color 91 | 92 | @property 93 | def rotate(self): 94 | return self._rotate 95 | 96 | @property 97 | def fsize(self): 98 | return self._fsize 99 | 100 | @property 101 | def position_x(self): 102 | return self._position_x 103 | 104 | @property 105 | def position_y(self): 106 | return self._position_y 107 | 108 | @property 109 | def mask(self): 110 | return self._mask 111 | 112 | def set_x(self, pos): 113 | self._position_x = pos 114 | 115 | def set_y(self, pos): 116 | self._position_y = pos 117 | -------------------------------------------------------------------------------- /model/utils.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | import base64 3 | import os 4 | import random 5 | from io import BytesIO 6 | 7 | from PIL import Image 8 | from PIL.ImageDraw import Draw 9 | 10 | 11 | class CaptchaUtils(object): 12 | @staticmethod 13 | def random_choice_from(_range): 14 | return random.choice(_range) 15 | 16 | @staticmethod 17 | def random_color_bg(): 18 | bg = [0xF0D8F0, 0xF0D8FF, 0xC0F0D8, 0xF0F0C0, 0xD8F0C0, 0xD8C0F0, 0xD8C0D8, 0xC0D8C0, 0xF0D8D8, 19 | 0xF0C0C0, 0xC0C0F0, 0xD8D8FF] 20 | return CaptchaUtils.get_rgb(CaptchaUtils.random_choice_from(bg), 160) 21 | 22 | @staticmethod 23 | def random_color_fg(): 24 | bg = [0x301878, 0x184830, 0x606030, 0x603018, 0x601878, 0x303078, 0x303030, 0x186018, 0x303090, 0x304860, 25 | 0x306048, 0x304848, 0x481860, 0x181818, 0x186030, 0x606048, 0x181848, 0x487818, 0x607830] 26 | return CaptchaUtils.get_rgb(CaptchaUtils.random_choice_from(bg)) 27 | 28 | @staticmethod 29 | def draw_line(image, start_p, end_p, color, wdith=2): 30 | points = [start_p[0], start_p[1], end_p[0], end_p[1]] 31 | Draw(image).line(points, fill=color, width=wdith) 32 | 33 | @staticmethod 34 | def draw_rectangle(image, box, color): 35 | points = [(box[0], box[1]), (box[0] + box[2], box[1]), (box[0] + box[2], box[1] + box[3]), 36 | (box[0], box[1] + box[3]), (box[0], box[1])] 37 | 38 | for index in range(len(points) - 1): 39 | CaptchaUtils.draw_line(image, points[index], points[index + 1], color) 40 | 41 | @staticmethod 42 | def draw_dot(image, color, width=2): 43 | w, h = image.size 44 | draw = Draw(image) 45 | x1 = random.randint(0, w) 46 | y1 = random.randint(0, h) 47 | draw.line((x1, y1, x1 - 1, y1 - 1), fill=color, width=width) 48 | 49 | @staticmethod 50 | def get_rgb(color_hex, op=None): 51 | if isinstance(color_hex, str): 52 | color_hex = int(color_hex, 16) 53 | 54 | if op is None: 55 | return (color_hex & 0xff0000) >> 16, (color_hex & 0x00ff00) >> 8, (color_hex & 0x0000ff) 56 | else: 57 | return ( 58 | (color_hex & 0xff0000) >> 16, (color_hex & 0x00ff00) >> 8, (color_hex & 0x0000ff), 59 | random.randint(op, 200)) 60 | 61 | @staticmethod 62 | def random_point(w, h): 63 | return random.randint(0, w), random.randint(0, h) 64 | 65 | @staticmethod 66 | def transform_base64_to_image(base64_str, image_path, image_name): 67 | if not os.path.isdir(image_path): 68 | os.makedirs(image_path) 69 | 70 | with open(os.path.join(image_path, image_name), "wb") as fh: 71 | fh.write(base64.decodebytes(bytes(base64_str, "utf-8"))) 72 | 73 | @staticmethod 74 | def convert_gif_to_jpg(gif_file, jpg_file_path): 75 | try: 76 | im = Image.open(gif_file) 77 | except IOError: 78 | print("converting failed while converting gif to jpg.") 79 | return -1 80 | 81 | i = 0 82 | mypalette = im.getpalette() 83 | # print(gif_file) 84 | try: 85 | while 1: 86 | im.putpalette(mypalette) 87 | new_im = Image.new("RGB", im.size) 88 | new_im.paste(im) 89 | new_im.save(jpg_file_path) 90 | 91 | i += 1 92 | im.seek(im.tell() + 1) 93 | 94 | except EOFError: 95 | pass # end of sequence 96 | 97 | @staticmethod 98 | def convert_gif_2_jpg(gif_base64): 99 | bas = base64.decodebytes(bytes(gif_base64, "utf-8")) 100 | im = Image.open(BytesIO(bas)) 101 | i = 0 102 | mypalette = im.getpalette() 103 | base64_jpgs = [] 104 | try: 105 | while 1: 106 | im.putpalette(mypalette) 107 | new_im = Image.new("RGB", im.size) 108 | new_im.paste(im) 109 | buffered = BytesIO() 110 | new_im.save(buffered, format="JPEG") 111 | img_data_base64 = base64.b64encode(buffered.getvalue()) 112 | base64_jpgs.append(img_data_base64) 113 | i += 1 114 | im.seek(im.tell() + 1) 115 | 116 | except EOFError: 117 | pass 118 | 119 | return base64_jpgs 120 | -------------------------------------------------------------------------------- /output/58gua_kao/138-13049954.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/58gua_kao/138-13049954.jpg -------------------------------------------------------------------------------- /output/58gua_kao/153-4856-9254.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/58gua_kao/153-4856-9254.jpg -------------------------------------------------------------------------------- /output/58gua_kao/155-0416-8055.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/58gua_kao/155-0416-8055.jpg -------------------------------------------------------------------------------- /output/demo/圪趟照虎.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/demo/圪趟照虎.jpg -------------------------------------------------------------------------------- /output/demo/殓蜒细睿.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/demo/殓蜒细睿.jpg -------------------------------------------------------------------------------- /output/demo/通疝纽翻.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/demo/通疝纽翻.jpg -------------------------------------------------------------------------------- /output/icp/6NJ6FU.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/icp/6NJ6FU.jpg -------------------------------------------------------------------------------- /output/icp/9NPVXP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/icp/9NPVXP.jpg -------------------------------------------------------------------------------- /output/icp/NU6RS6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/icp/NU6RS6.jpg -------------------------------------------------------------------------------- /output/jingdong/9nEL.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/jingdong/9nEL.jpg -------------------------------------------------------------------------------- /output/jingdong/DK67.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/jingdong/DK67.jpg -------------------------------------------------------------------------------- /output/jingdong/o55v.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/output/jingdong/o55v.jpg -------------------------------------------------------------------------------- /resources/background/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/background/2.jpg -------------------------------------------------------------------------------- /resources/background/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/background/3.jpg -------------------------------------------------------------------------------- /resources/background/color.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/background/color.jpg -------------------------------------------------------------------------------- /resources/corpus/common_chinese.txt: -------------------------------------------------------------------------------- 1 | 啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑班搬扳般颁板版扮拌伴瓣半办绊邦帮梆榜膀绑棒磅蚌镑傍谤苞胞包褒剥薄雹保堡饱宝抱报暴豹鲍爆杯碑悲卑北辈背贝钡倍狈备惫焙被奔苯本笨崩绷甭泵蹦迸逼鼻比鄙笔彼碧蓖蔽毕毙毖币庇痹闭敝弊必辟壁臂避陛鞭边编贬扁便变卞辨辩辫遍标彪膘表鳖憋别瘪彬斌濒滨宾摈兵冰柄丙秉饼炳病并玻菠播拨钵波博勃搏铂箔伯帛舶脖膊渤泊驳捕卜哺补埠不布步簿部怖擦猜裁材才财睬踩采彩菜蔡餐参蚕残惭惨灿苍舱仓沧藏操糙槽曹草厕策侧册测层蹭插叉茬茶查碴搽察岔差诧拆柴豺搀掺蝉馋谗缠铲产阐颤昌猖场尝常长偿肠厂敞畅唱倡超抄钞朝嘲潮巢吵炒车扯撤掣彻澈郴臣辰尘晨忱沉陈趁衬撑称城橙成呈乘程惩澄诚承逞骋秤吃痴持匙池迟弛驰耻齿侈尺赤翅斥炽充冲虫崇宠抽酬畴踌稠愁筹仇绸瞅丑臭初出橱厨躇锄雏滁除楚础储矗搐触处揣川穿椽传船喘串疮窗幢床闯创吹炊捶锤垂春椿醇唇淳纯蠢戳绰疵茨磁雌辞慈瓷词此刺赐次聪葱囱匆从丛凑粗醋簇促蹿篡窜摧崔催脆瘁粹淬翠村存寸磋撮搓措挫错搭达答瘩打大呆歹傣戴带殆代贷袋待逮怠耽担丹单郸掸胆旦氮但惮淡诞弹蛋当挡党荡档刀捣蹈倒岛祷导到稻悼道盗德得的蹬灯登等瞪凳邓堤低滴迪敌笛狄涤翟嫡抵底地蒂第帝弟递缔颠掂滇碘点典靛垫电佃甸店惦奠淀殿碉叼雕凋刁掉吊钓调跌爹碟蝶迭谍叠丁盯叮钉顶鼎锭定订丢东冬董懂动栋侗恫冻洞兜抖斗陡豆逗痘都督毒犊独读堵睹赌杜镀肚度渡妒端短锻段断缎堆兑队对墩吨蹲敦顿囤钝盾遁掇哆多夺垛躲朵跺舵剁惰堕蛾峨鹅俄额讹娥恶厄扼遏鄂饿恩而儿耳尔饵洱二贰发罚筏伐乏阀法珐藩帆番翻樊矾钒繁凡烦反返范贩犯饭泛坊芳方肪房防妨仿访纺放菲非啡飞肥匪诽吠肺废沸费芬酚吩氛分纷坟焚汾粉奋份忿愤粪丰封枫蜂峰锋风疯烽逢冯缝讽奉凤佛否夫敷肤孵扶拂辐幅氟符伏俘服浮涪福袱弗甫抚辅俯釜斧脯腑府腐赴副覆赋复傅付阜父腹负富讣附妇缚咐噶嘎该改概钙盖溉干甘杆柑竿肝赶感秆敢赣冈刚钢缸肛纲岗港杠篙皋高膏羔糕搞镐稿告哥歌搁戈鸽胳疙割革葛格蛤阁隔铬个各给根跟耕更庚羹埂耿梗工攻功恭龚供躬公宫弓巩汞拱贡共钩勾沟苟狗垢构购够辜菇咕箍估沽孤姑鼓古蛊骨谷股故顾固雇刮瓜剐寡挂褂乖拐怪棺关官冠观管馆罐惯灌贯光广逛瑰规圭硅归龟闺轨鬼诡癸桂柜跪贵刽辊滚棍锅郭国果裹过哈骸孩海氦亥害骇酣憨邯韩含涵寒函喊罕翰撼捍旱憾悍焊汗汉夯杭航壕嚎豪毫郝好耗号浩呵喝荷菏核禾和何合盒貉阂河涸赫褐鹤贺嘿黑痕很狠恨哼亨横衡恒轰哄烘虹鸿洪宏弘红喉侯猴吼厚候后呼乎忽瑚壶葫胡蝴狐糊湖弧虎唬护互沪户花哗华猾滑画划化话槐徊怀淮坏欢环桓还缓换患唤痪豢焕涣宦幻荒慌黄磺蝗簧皇凰惶煌晃幌恍谎灰挥辉徽恢蛔回毁悔慧卉惠晦贿秽会烩汇讳诲绘荤昏婚魂浑混豁活伙火获或惑霍货祸击圾基机畸稽积箕肌饥迹激讥鸡姬绩缉吉极棘辑籍集及急疾汲即嫉级挤几脊己蓟技冀季伎祭剂悸济寄寂计记既忌际妓继纪嘉枷夹佳家加荚颊贾甲钾假稼价架驾嫁歼监坚尖笺间煎兼肩艰奸缄茧检柬碱硷拣捡简俭剪减荐槛鉴践贱见键箭件健舰剑饯渐溅涧建僵姜将浆江疆蒋桨奖讲匠酱降蕉椒礁焦胶交郊浇骄娇嚼搅铰矫侥脚狡角饺缴绞剿教酵轿较叫窖揭接皆秸街阶截劫节桔杰捷睫竭洁结解姐戒藉芥界借介疥诫届巾筋斤金今津襟紧锦仅谨进靳晋禁近烬浸尽劲荆兢茎睛晶鲸京惊精粳经井警景颈静境敬镜径痉靖竟竞净炯窘揪究纠玖韭久灸九酒厩救旧臼舅咎就疚鞠拘狙疽居驹菊局咀矩举沮聚拒据巨具距踞锯俱句惧炬剧捐鹃娟倦眷卷绢撅攫抉掘倔爵觉决诀绝均菌钧军君峻俊竣浚郡骏喀咖卡咯开揩楷凯慨刊堪勘坎砍看康慷糠扛抗亢炕考拷烤靠坷苛柯棵磕颗科壳咳可渴克刻客课肯啃垦恳坑吭空恐孔控抠口扣寇枯哭窟苦酷库裤夸垮挎跨胯块筷侩快宽款匡筐狂框矿眶旷况亏盔岿窥葵奎魁傀馈愧溃坤昆捆困括扩廓阔垃拉喇蜡腊辣啦莱来赖蓝婪栏拦篮阑兰澜谰揽览懒缆烂滥琅榔狼廊郎朗浪捞劳牢老佬姥酪烙涝勒乐雷镭蕾磊累儡垒擂肋类泪棱楞冷厘梨犁黎篱狸离漓理李里鲤礼莉荔吏栗丽厉励砾历利傈例俐痢立粒沥隶力璃哩俩联莲连镰廉怜涟帘敛脸链恋炼练粮凉梁粱良两辆量晾亮谅撩聊僚疗燎寥辽潦了撂镣廖料列裂烈劣猎琳林磷霖临邻鳞淋凛赁吝拎玲菱零龄铃伶羚凌灵陵岭领另令溜琉榴硫馏留刘瘤流柳六龙聋咙笼窿隆垄拢陇楼娄搂篓漏陋芦卢颅庐炉掳卤虏鲁麓碌露路赂鹿潞禄录陆戮驴吕铝侣旅履屡缕虑氯律率滤绿峦挛孪滦卵乱掠略抡轮伦仑沦纶论萝螺罗逻锣箩骡裸落洛骆络妈麻玛码蚂马骂嘛吗埋买麦卖迈脉瞒馒蛮满蔓曼慢漫谩芒茫盲氓忙莽猫茅锚毛矛铆卯茂冒帽貌贸么玫枚梅酶霉煤没眉媒镁每美昧寐妹媚门闷们萌蒙檬盟锰猛梦孟眯醚靡糜迷谜弥米秘觅泌蜜密幂棉眠绵冕免勉娩缅面苗描瞄藐秒渺庙妙蔑灭民抿皿敏悯闽明螟鸣铭名命谬摸摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌谋牟某拇牡亩姆母墓暮幕募慕木目睦牧穆拿哪呐钠那娜纳氖乃奶耐奈南男难囊挠脑恼闹淖呢馁内嫩能妮霓倪泥尼拟你匿腻逆溺蔫拈年碾撵捻念娘酿鸟尿捏聂孽啮镊镍涅您柠狞凝宁拧泞牛扭钮纽脓浓农弄奴努怒女暖虐疟挪懦糯诺哦欧鸥殴藕呕偶沤啪趴爬帕怕琶拍排牌徘湃派攀潘盘磐盼畔判叛乓庞旁耪胖抛咆刨炮袍跑泡呸胚培裴赔陪配佩沛喷盆砰抨烹澎彭蓬棚硼篷膨朋鹏捧碰坯砒霹批披劈琵毗啤脾疲皮匹痞僻屁譬篇偏片骗飘漂瓢票撇瞥拼频贫品聘乒坪苹萍平凭瓶评屏坡泼颇婆破魄迫粕剖扑铺仆莆葡菩蒲埔朴圃普浦谱曝瀑期欺栖戚妻七凄漆柒沏其棋奇歧畦崎脐齐旗祈祁骑起岂乞企启契砌器气迄弃汽泣讫掐恰洽牵扦钎铅千迁签仟谦乾黔钱钳前潜遣浅谴堑嵌欠歉枪呛腔羌墙蔷强抢橇锹敲悄桥瞧乔侨巧鞘撬翘峭俏窍切茄且怯窃钦侵亲秦琴勤芹擒禽寝沁青轻氢倾卿清擎晴氰情顷请庆琼穷秋丘邱球求囚酋泅趋区蛆曲躯屈驱渠取娶龋趣去圈颧权醛泉全痊拳犬券劝缺炔瘸却鹊榷确雀裙群然燃冉染瓤壤攘嚷让饶扰绕惹热壬仁人忍韧任认刃妊纫扔仍日戎茸蓉荣融熔溶容绒冗揉柔肉茹蠕儒孺如辱乳汝入褥软阮蕊瑞锐闰润若弱撒洒萨腮鳃塞赛三叁伞散桑嗓丧搔骚扫嫂瑟色涩森僧莎砂杀刹沙纱傻啥煞筛晒珊苫杉山删煽衫闪陕擅赡膳善汕扇缮墒伤商赏晌上尚裳梢捎稍烧芍勺韶少哨邵绍奢赊蛇舌舍赦摄射慑涉社设砷申呻伸身深娠绅神沈审婶甚肾慎渗声生甥牲升绳省盛剩胜圣师失狮施湿诗尸虱十石拾时什食蚀实识史矢使屎驶始式示士世柿事拭誓逝势是嗜噬适仕侍释饰氏市恃室视试收手首守寿授售受瘦兽蔬枢梳殊抒输叔舒淑疏书赎孰熟薯暑曙署蜀黍鼠属术述树束戍竖墅庶数漱恕刷耍摔衰甩帅栓拴霜双爽谁水睡税吮瞬顺舜说硕朔烁斯撕嘶思私司丝死肆寺嗣四伺似饲巳松耸怂颂送宋讼诵搜艘擞嗽苏酥俗素速粟僳塑溯宿诉肃酸蒜算虽隋随绥髓碎岁穗遂隧祟孙损笋蓑梭唆缩琐索锁所塌他它她塔獭挞蹋踏胎苔抬台泰酞太态汰坍摊贪瘫滩坛檀痰潭谭谈坦毯袒碳探叹炭汤塘搪堂棠膛唐糖倘躺淌趟烫掏涛滔绦萄桃逃淘陶讨套特藤腾疼誊梯剔踢锑提题蹄啼体替嚏惕涕剃屉天添填田甜恬舔腆挑条迢眺跳贴铁帖厅听烃汀廷停亭庭挺艇通桐酮瞳同铜彤童桶捅筒统痛偷投头透凸秃突图徒途涂屠土吐兔湍团推颓腿蜕褪退吞屯臀拖托脱鸵陀驮驼椭妥拓唾挖哇蛙洼娃瓦袜歪外豌弯湾玩顽丸烷完碗挽晚皖惋宛婉万腕汪王亡枉网往旺望忘妄威巍微危韦违桅围唯惟为潍维苇萎委伟伪尾纬未蔚味畏胃喂魏位渭谓尉慰卫瘟温蚊文闻纹吻稳紊问嗡翁瓮挝蜗涡窝我斡卧握沃巫呜钨乌污诬屋无芜梧吾吴毋武五捂午舞伍侮坞戊雾晤物勿务悟误昔熙析西硒矽晰嘻吸锡牺稀息希悉膝夕惜熄烯溪汐犀檄袭席习媳喜铣洗系隙戏细瞎虾匣霞辖暇峡侠狭下厦夏吓掀锨先仙鲜纤咸贤衔舷闲涎弦嫌显险现献县腺馅羡宪陷限线相厢镶香箱襄湘乡翔祥详想响享项巷橡像向象萧硝霄削哮嚣销消宵淆晓小孝校肖啸笑效楔些歇蝎鞋协挟携邪斜胁谐写械卸蟹懈泄泻谢屑薪芯锌欣辛新忻心信衅星腥猩惺兴刑型形邢行醒幸杏性姓兄凶胸匈汹雄熊休修羞朽嗅锈秀袖绣墟戌需虚嘘须徐许蓄酗叙旭序畜恤絮婿绪续轩喧宣悬旋玄选癣眩绚靴薛学穴雪血勋熏循旬询寻驯巡殉汛训讯逊迅压押鸦鸭呀丫芽牙蚜崖衙涯雅哑亚讶焉咽阉烟淹盐严研蜒岩延言颜阎炎沿奄掩眼衍演艳堰燕厌砚雁唁彦焰宴谚验殃央鸯秧杨扬佯疡羊洋阳氧仰痒养样漾邀腰妖瑶摇尧遥窑谣姚咬舀药要耀椰噎耶爷野冶也页掖业叶曳腋夜液一壹医揖铱依伊衣颐夷遗移仪胰疑沂宜姨彝椅蚁倚已乙矣以艺抑易邑屹亿役臆逸肄疫亦裔意毅忆义益溢诣议谊译异翼翌绎茵荫因殷音阴姻吟银淫寅饮尹引隐印英樱婴鹰应缨莹萤营荧蝇迎赢盈影颖硬映哟拥佣臃痈庸雍踊蛹咏泳涌永恿勇用幽优悠忧尤由邮铀犹油游酉有友右佑釉诱又幼迂淤于盂榆虞愚舆余俞逾鱼愉渝渔隅予娱雨与屿禹宇语羽玉域芋郁吁遇喻峪御愈欲狱育誉浴寓裕预豫驭鸳渊冤元垣袁原援辕园员圆猿源缘远苑愿怨院曰约越跃钥岳粤月悦阅耘云郧匀陨允运蕴酝晕韵孕匝砸杂栽哉灾宰载再在咱攒暂赞赃脏葬遭糟凿藻枣早澡蚤躁噪造皂灶燥责择则泽贼怎增憎曾赠扎喳渣札轧铡闸眨栅榨咋乍炸诈摘斋宅窄债寨瞻毡詹粘沾盏斩辗崭展蘸栈占战站湛绽樟章彰漳张掌涨杖丈帐账仗胀瘴障招昭找沼赵照罩兆肇召遮折哲蛰辙者锗蔗这浙珍斟真甄砧臻贞针侦枕疹诊震振镇阵蒸挣睁征狰争怔整拯正政帧症郑证芝枝支吱蜘知肢脂汁之织职直植殖执值侄址指止趾只旨纸志挚掷至致置帜峙制智秩稚质炙痔滞治窒中盅忠钟衷终种肿重仲众舟周州洲诌粥轴肘帚咒皱宙昼骤珠株蛛朱猪诸诛逐竹烛煮拄瞩嘱主著柱助蛀贮铸筑住注祝驻抓爪拽专砖转撰赚篆桩庄装妆撞壮状椎锥追赘坠缀谆准捉拙卓桌琢茁酌啄着灼浊兹咨资姿滋淄孜紫仔籽滓子自渍字鬃棕踪宗综总纵邹走奏揍租足卒族祖诅阻组钻纂嘴醉最罪尊遵昨左佐柞做作坐座亍丌兀丐廿卅丕亘丞鬲孬噩丨禺丿匕乇夭爻卮氐囟胤馗毓睾鼗丶亟鼐乜乩亓芈孛啬嘏仄厍厝厣厥厮靥赝匚叵匦匮匾赜卦卣刂刈刎刭刳刿剀剌剞剡剜蒯剽劂劁劐劓冂罔亻仃仉仂仨仡仫仞伛仳伢佤仵伥伧伉伫佞佧攸佚佝佟佗伲伽佶佴侑侉侃侏佾佻侪佼侬侔俦俨俪俅俚俣俜俑俟俸倩偌俳倬倏倮倭俾倜倌倥倨偾偃偕偈偎偬偻傥傧傩傺僖儆僭僬僦僮儇儋仝氽佘佥俎龠汆籴兮巽黉馘冁夔勹匍訇匐凫夙兕亠兖亳衮袤亵脔裒禀嬴蠃羸冫冱冽冼凇冖冢冥讠讦讧讪讴讵讷诂诃诋诏诎诒诓诔诖诘诙诜诟诠诤诨诩诮诰诳诶诹诼诿谀谂谄谇谌谏谑谒谔谕谖谙谛谘谝谟谠谡谥谧谪谫谮谯谲谳谵谶卩卺阝阢阡阱阪阽阼陂陉陔陟陧陬陲陴隈隍隗隰邗邛邝邙邬邡邴邳邶邺邸邰郏郅邾郐郄郇郓郦郢郜郗郛郫郯郾鄄鄢鄞鄣鄱鄯鄹酃酆刍奂劢劬劭劾哿勐勖勰叟燮矍廴凵凼鬯厶弁畚巯坌垩垡塾墼壅壑圩圬圪圳圹圮圯坜圻坂坩垅坫垆坼坻坨坭坶坳垭垤垌垲埏垧垴垓垠埕埘埚埙埒垸埴埯埸埤埝堋堍埽埭堀堞堙塄堠塥塬墁墉墚墀馨鼙懿艹艽艿芏芊芨芄芎芑芗芙芫芸芾芰苈苊苣芘芷芮苋苌苁芩芴芡芪芟苄苎芤苡茉苷苤茏茇苜苴苒苘茌苻苓茑茚茆茔茕苠苕茜荑荛荜茈莒茼茴茱莛荞茯荏荇荃荟荀茗荠茭茺茳荦荥荨茛荩荬荪荭荮莰荸莳莴莠莪莓莜莅荼莶莩荽莸荻莘莞莨莺莼菁萁菥菘堇萘萋菝菽菖萜萸萑萆菔菟萏萃菸菹菪菅菀萦菰菡葜葑葚葙葳蒇蒈葺蒉葸萼葆葩葶蒌蒎萱葭蓁蓍蓐蓦蒽蓓蓊蒿蒺蓠蒡蒹蒴蒗蓥蓣蔌甍蔸蓰蔹蔟蔺蕖蔻蓿蓼蕙蕈蕨蕤蕞蕺瞢蕃蕲蕻薤薨薇薏蕹薮薜薅薹薷薰藓藁藜藿蘧蘅蘩蘖蘼廾弈夼奁耷奕奚奘匏尢尥尬尴扌扪抟抻拊拚拗拮挢拶挹捋捃掭揶捱捺掎掴捭掬掊捩掮掼揲揸揠揿揄揞揎摒揆掾摅摁搋搛搠搌搦搡摞撄摭撖摺撷撸撙撺擀擐擗擤擢攉攥攮弋忒甙弑卟叱叽叩叨叻吒吖吆呋呒呓呔呖呃吡呗呙吣吲咂咔呷呱呤咚咛咄呶呦咝哐咭哂咴哒咧咦哓哔呲咣哕咻咿哌哙哚哜咩咪咤哝哏哞唛哧唠哽唔哳唢唣唏唑唧唪啧喏喵啉啭啁啕唿啐唼唷啖啵啶啷唳唰啜喋嗒喃喱喹喈喁喟啾嗖喑啻嗟喽喾喔喙嗪嗷嗉嘟嗑嗫嗬嗔嗦嗝嗄嗯嗥嗲嗳嗌嗍嗨嗵嗤辔嘞嘈嘌嘁嘤嘣嗾嘀嘧嘭噘嘹噗嘬噍噢噙噜噌噔嚆噤噱噫噻噼嚅嚓嚯囔囗囝囡囵囫囹囿圄圊圉圜帏帙帔帑帱帻帼帷幄幔幛幞幡岌屺岍岐岖岈岘岙岑岚岜岵岢岽岬岫岱岣峁岷峄峒峤峋峥崂崃崧崦崮崤崞崆崛嵘崾崴崽嵬嵛嵯嵝嵫嵋嵊嵩嵴嶂嶙嶝豳嶷巅彳彷徂徇徉後徕徙徜徨徭徵徼衢彡犭犰犴犷犸狃狁狎狍狒狨狯狩狲狴狷猁狳猃狺狻猗猓猡猊猞猝猕猢猹猥猬猸猱獐獍獗獠獬獯獾舛夥飧夤夂饣饧饨饩饪饫饬饴饷饽馀馄馇馊馍馐馑馓馔馕庀庑庋庖庥庠庹庵庾庳赓廒廑廛廨廪膺忄忉忖忏怃忮怄忡忤忾怅怆忪忭忸怙怵怦怛怏怍怩怫怊怿怡恸恹恻恺恂恪恽悖悚悭悝悃悒悌悛惬悻悱惝惘惆惚悴愠愦愕愣惴愀愎愫慊慵憬憔憧憷懔懵忝隳闩闫闱闳闵闶闼闾阃阄阆阈阊阋阌阍阏阒阕阖阗阙阚丬爿戕氵汔汜汊沣沅沐沔沌汨汩汴汶沆沩泐泔沭泷泸泱泗沲泠泖泺泫泮沱泓泯泾洹洧洌浃浈洇洄洙洎洫浍洮洵洚浏浒浔洳涑浯涞涠浞涓涔浜浠浼浣渚淇淅淞渎涿淠渑淦淝淙渖涫渌涮渫湮湎湫溲湟溆湓湔渲渥湄滟溱溘滠漭滢溥溧溽溻溷滗溴滏溏滂溟潢潆潇漤漕滹漯漶潋潴漪漉漩澉澍澌潸潲潼潺濑濉澧澹澶濂濡濮濞濠濯瀚瀣瀛瀹瀵灏灞宀宄宕宓宥宸甯骞搴寤寮褰寰蹇謇辶迓迕迥迮迤迩迦迳迨逅逄逋逦逑逍逖逡逵逶逭逯遄遑遒遐遨遘遢遛暹遴遽邂邈邃邋彐彗彖彘尻咫屐屙孱屣屦羼弪弩弭艴弼鬻屮妁妃妍妩妪妣妗姊妫妞妤姒妲妯姗妾娅娆姝娈姣姘姹娌娉娲娴娑娣娓婀婧婊婕娼婢婵胬媪媛婷婺媾嫫媲嫒嫔媸嫠嫣嫱嫖嫦嫘嫜嬉嬗嬖嬲嬷孀尕尜孚孥孳孑孓孢驵驷驸驺驿驽骀骁骅骈骊骐骒骓骖骘骛骜骝骟骠骢骣骥骧纟纡纣纥纨纩纭纰纾绀绁绂绉绋绌绐绔绗绛绠绡绨绫绮绯绱绲缍绶绺绻绾缁缂缃缇缈缋缌缏缑缒缗缙缜缛缟缡缢缣缤缥缦缧缪缫缬缭缯缰缱缲缳缵幺畿巛甾邕玎玑玮玢玟珏珂珑玷玳珀珉珈珥珙顼琊珩珧珞玺珲琏琪瑛琦琥琨琰琮琬琛琚瑁瑜瑗瑕瑙瑷瑭瑾璜璎璀璁璇璋璞璨璩璐璧瓒璺韪韫韬杌杓杞杈杩枥枇杪杳枘枧杵枨枞枭枋杷杼柰栉柘栊柩枰栌柙枵柚枳柝栀柃枸柢栎柁柽栲栳桠桡桎桢桄桤梃栝桕桦桁桧桀栾桊桉栩梵梏桴桷梓桫棂楮棼椟椠棹椤棰椋椁楗棣椐楱椹楠楂楝榄楫榀榘楸椴槌榇榈槎榉楦楣楹榛榧榻榫榭槔榱槁槊槟榕槠榍槿樯槭樗樘橥槲橄樾檠橐橛樵檎橹樽樨橘橼檑檐檩檗檫猷獒殁殂殇殄殒殓殍殚殛殡殪轫轭轱轲轳轵轶轸轷轹轺轼轾辁辂辄辇辋辍辎辏辘辚軎戋戗戛戟戢戡戥戤戬臧瓯瓴瓿甏甑甓攴旮旯旰昊昙杲昃昕昀炅曷昝昴昱昶昵耆晟晔晁晏晖晡晗晷暄暌暧暝暾曛曜曦曩贲贳贶贻贽赀赅赆赈赉赇赍赕赙觇觊觋觌觎觏觐觑牮犟牝牦牯牾牿犄犋犍犏犒挈挲掰搿擘耄毪毳毽毵毹氅氇氆氍氕氘氙氚氡氩氤氪氲攵敕敫牍牒牖爰虢刖肟肜肓肼朊肽肱肫肭肴肷胧胨胩胪胛胂胄胙胍胗朐胝胫胱胴胭脍脎胲胼朕脒豚脶脞脬脘脲腈腌腓腴腙腚腱腠腩腼腽腭腧塍媵膈膂膑滕膣膪臌朦臊膻臁膦欤欷欹歃歆歙飑飒飓飕飙飚殳彀毂觳斐齑斓於旆旄旃旌旎旒旖炀炜炖炝炻烀炷炫炱烨烊焐焓焖焯焱煳煜煨煅煲煊煸煺熘熳熵熨熠燠燔燧燹爝爨灬焘煦熹戾戽扃扈扉礻祀祆祉祛祜祓祚祢祗祠祯祧祺禅禊禚禧禳忑忐怼恝恚恧恁恙恣悫愆愍慝憩憝懋懑戆肀聿沓泶淼矶矸砀砉砗砘砑斫砭砜砝砹砺砻砟砼砥砬砣砩硎硭硖硗砦硐硇硌硪碛碓碚碇碜碡碣碲碹碥磔磙磉磬磲礅磴礓礤礞礴龛黹黻黼盱眄眍盹眇眈眚眢眙眭眦眵眸睐睑睇睃睚睨睢睥睿瞍睽瞀瞌瞑瞟瞠瞰瞵瞽町畀畎畋畈畛畲畹疃罘罡罟詈罨罴罱罹羁罾盍盥蠲钅钆钇钋钊钌钍钏钐钔钗钕钚钛钜钣钤钫钪钭钬钯钰钲钴钶钷钸钹钺钼钽钿铄铈铉铊铋铌铍铎铐铑铒铕铖铗铙铘铛铞铟铠铢铤铥铧铨铪铩铫铮铯铳铴铵铷铹铼铽铿锃锂锆锇锉锊锍锎锏锒锓锔锕锖锘锛锝锞锟锢锪锫锩锬锱锲锴锶锷锸锼锾锿镂锵镄镅镆镉镌镎镏镒镓镔镖镗镘镙镛镞镟镝镡镢镤镥镦镧镨镩镪镫镬镯镱镲镳锺矧矬雉秕秭秣秫稆嵇稃稂稞稔稹稷穑黏馥穰皈皎皓皙皤瓞瓠甬鸠鸢鸨鸩鸪鸫鸬鸲鸱鸶鸸鸷鸹鸺鸾鹁鹂鹄鹆鹇鹈鹉鹋鹌鹎鹑鹕鹗鹚鹛鹜鹞鹣鹦鹧鹨鹩鹪鹫鹬鹱鹭鹳疒疔疖疠疝疬疣疳疴疸痄疱疰痃痂痖痍痣痨痦痤痫痧瘃痱痼痿瘐瘀瘅瘌瘗瘊瘥瘘瘕瘙瘛瘼瘢瘠癀瘭瘰瘿瘵癃瘾瘳癍癞癔癜癖癫癯翊竦穸穹窀窆窈窕窦窠窬窨窭窳衤衩衲衽衿袂袢裆袷袼裉裢裎裣裥裱褚裼裨裾裰褡褙褓褛褊褴褫褶襁襦襻疋胥皲皴矜耒耔耖耜耠耢耥耦耧耩耨耱耋耵聃聆聍聒聩聱覃顸颀颃颉颌颍颏颔颚颛颞颟颡颢颥颦虍虔虬虮虿虺虼虻蚨蚍蚋蚬蚝蚧蚣蚪蚓蚩蚶蛄蚵蛎蚰蚺蚱蚯蛉蛏蚴蛩蛱蛲蛭蛳蛐蜓蛞蛴蛟蛘蛑蜃蜇蛸蜈蜊蜍蜉蜣蜻蜞蜥蜮蜚蜾蝈蜴蜱蜩蜷蜿螂蜢蝽蝾蝻蝠蝰蝌蝮螋蝓蝣蝼蝤蝙蝥螓螯螨蟒蟆螈螅螭螗螃螫蟥螬螵螳蟋蟓螽蟑蟀蟊蟛蟪蟠蟮蠖蠓蟾蠊蠛蠡蠹蠼缶罂罄罅舐竺竽笈笃笄笕笊笫笏筇笸笪笙笮笱笠笥笤笳笾笞筘筚筅筵筌筝筠筮筻筢筲筱箐箦箧箸箬箝箨箅箪箜箢箫箴篑篁篌篝篚篥篦篪簌篾篼簏簖簋簟簪簦簸籁籀臾舁舂舄臬衄舡舢舣舭舯舨舫舸舻舳舴舾艄艉艋艏艚艟艨衾袅袈裘裟襞羝羟羧羯羰羲籼敉粑粝粜粞粢粲粼粽糁糇糌糍糈糅糗糨艮暨羿翎翕翥翡翦翩翮翳糸絷綦綮繇纛麸麴赳趄趔趑趱赧赭豇豉酊酐酎酏酤酢酡酰酩酯酽酾酲酴酹醌醅醐醍醑醢醣醪醭醮醯醵醴醺豕鹾趸跫踅蹙蹩趵趿趼趺跄跖跗跚跞跎跏跛跆跬跷跸跣跹跻跤踉跽踔踝踟踬踮踣踯踺蹀踹踵踽踱蹉蹁蹂蹑蹒蹊蹰蹶蹼蹯蹴躅躏躔躐躜躞豸貂貊貅貘貔斛觖觞觚觜觥觫觯訾謦靓雩雳雯霆霁霈霏霎霪霭霰霾龀龃龅龆龇龈龉龊龌黾鼋鼍隹隼隽雎雒瞿雠銎銮鋈錾鍪鏊鎏鐾鑫鱿鲂鲅鲆鲇鲈稣鲋鲎鲐鲑鲒鲔鲕鲚鲛鲞鲟鲠鲡鲢鲣鲥鲦鲧鲨鲩鲫鲭鲮鲰鲱鲲鲳鲴鲵鲶鲷鲺鲻鲼鲽鳄鳅鳆鳇鳊鳋鳌鳍鳎鳏鳐鳓鳔鳕鳗鳘鳙鳜鳝鳟鳢靼鞅鞑鞒鞔鞯鞫鞣鞲鞴骱骰骷鹘骶骺骼髁髀髅髂髋髌髑魅魃魇魉魈魍魑飨餍餮饕饔髟髡髦髯髫髻髭髹鬈鬏鬓鬟鬣麽麾縻麂麇麈麋麒鏖麝麟黛黜黝黠黟黢黩黧黥黪黯鼢鼬鼯鼹鼷鼽鼾齄 -------------------------------------------------------------------------------- /resources/corpus/text.csv: -------------------------------------------------------------------------------- 1 | 拉枯折朽 2 | 拉枯折朽 -------------------------------------------------------------------------------- /resources/corpus/top_level_chinese.txt: -------------------------------------------------------------------------------- 1 | 一乙二十丁厂七卜八人入儿匕几九刁了刀力乃又三干于亏工土士才下寸大丈与万上小口山巾千乞川亿个夕久么勺凡丸及广亡门丫义之尸己已巳弓子卫也女刃飞习叉马乡丰王开井天夫元无云专丐扎艺木五支厅不犬太区历歹友尤匹车巨牙屯戈比互切瓦止少曰日中贝冈内水见午牛手气毛壬升夭长仁什片仆化仇币仍仅斤爪反介父从仑今凶分乏公仓月氏勿欠风丹匀乌勾凤六文亢方火为斗忆计订户认冗讥心尺引丑巴孔队办以允予邓劝双书幻玉刊未末示击打巧正扑卉扒功扔去甘世艾古节本术可丙左厉石右布夯戊龙平灭轧东卡北占凸卢业旧帅归旦目且叶甲申叮电号田由只叭史央兄叽叼叫叩叨另叹冉皿凹囚四生矢失乍禾丘付仗代仙们仪白仔他斥瓜乎丛令用甩印尔乐句匆册卯犯外处冬鸟务包饥主市立冯玄闪兰半汁汇头汉宁穴它讨写让礼训议必讯记永司尼民弗弘出辽奶奴召加皮边孕发圣对台矛纠母幼丝邦式迂刑戎动扛寺吉扣考托老巩圾执扩扫地场扬耳芋共芒亚芝朽朴机权过臣吏再协西压厌戌在百有存而页匠夸夺灰达列死成夹夷轨邪尧划迈毕至此贞师尘尖劣光当早吁吐吓虫曲团吕同吊吃因吸吗吆屿屹岁帆回岂则刚网肉年朱先丢廷舌竹迁乔迄伟传乒乓休伍伏优臼伐延仲件任伤价伦份华仰仿伙伪自伊血向似后行舟全会杀合兆企众爷伞创肌肋朵杂危旬旨旭负匈名各多争色壮冲妆冰庄庆亦刘齐交衣次产决亥充妄闭问闯羊并关米灯州汗污江汛池汝汤忙兴宇守宅字安讲讳军讶许讹论讼农讽设访诀寻那迅尽导异弛孙阵阳收阶阴防奸如妇妃好她妈戏羽观欢买红驮纤驯约级纪驰纫巡寿弄麦玖玛形进戒吞远违韧运扶抚坛技坏抠扰扼拒找批址扯走抄贡汞坝攻赤折抓扳抡扮抢孝坎均抑抛投坟坑抗坊抖护壳志块扭声把报拟却抒劫芙芜苇芽花芹芥芬苍芳严芦芯劳克芭苏杆杠杜材村杖杏杉巫极李杨求甫匣更束吾豆两酉丽医辰励否还尬歼来连轩步卤坚肖旱盯呈时吴助县里呆吱吠呕园旷围呀吨足邮男困吵串员呐听吟吩呛吻吹呜吭吧邑吼囤别吮岖岗帐财针钉牡告我乱利秃秀私每兵估体何佐佑但伸佃作伯伶佣低你住位伴身皂伺佛囱近彻役返余希坐谷妥含邻岔肝肛肚肘肠龟甸免狂犹狈角删条彤卵灸岛刨迎饭饮系言冻状亩况床库庇疗吝应这冷庐序辛弃冶忘闰闲间闷判兑灶灿灼弟汪沐沛汰沥沙汽沃沦汹泛沧没沟沪沈沉沁怀忧忱快完宋宏牢究穷灾良证启评补初社祀识诈诉罕诊词译君灵即层屁尿尾迟局改张忌际陆阿陈阻附坠妓妙妖姊妨妒努忍劲矣鸡纬驱纯纱纲纳驳纵纷纸纹纺驴纽奉玩环武青责现玫表规抹卦坷坯拓拢拔坪拣坦担坤押抽拐拖者拍顶拆拎拥抵拘势抱拄垃拉拦幸拌拧拂拙招坡披拨择抬拇拗其取茉苦昔苛若茂苹苗英苟苑苞范直茁茄茎苔茅枉林枝杯枢柜枚析板松枪枫构杭杰述枕丧或画卧事刺枣雨卖郁矾矿码厕奈奔奇奋态欧殴垄妻轰顷转斩轮软到非叔歧肯齿些卓虎虏肾贤尚旺具味果昆国哎咕昌呵畅明易咙昂迪典固忠呻咒咋咐呼鸣咏呢咄咖岸岩帖罗帜帕岭凯败账贩贬购贮图钓制知迭氛垂牧物乖刮秆和季委秉佳侍岳供使例侠侥版侄侦侣侧凭侨佩货侈依卑的迫质欣征往爬彼径所舍金刹命肴斧爸采觅受乳贪念贫忿肤肺肢肿胀朋股肮肪肥服胁周昏鱼兔狐忽狗狞备饰饱饲变京享庞店夜庙府底疟疙疚剂卒郊庚废净盲放刻育氓闸闹郑券卷单炬炒炊炕炎炉沫浅法泄沽河沾泪沮油泊沿泡注泣泞泻泌泳泥沸沼波泼泽治怔怯怖性怕怜怪怡学宝宗定宠宜审宙官空帘宛实试郎诗肩房诚衬衫视祈话诞诡询该详建肃录隶帚屉居届刷屈弧弥弦承孟陋陌孤陕降函限妹姑姐姓妮始姆迢驾叁参艰线练组绅细驶织驹终驻绊驼绍绎经贯契贰奏春帮玷珍玲珊玻毒型拭挂封持拷拱项垮挎城挟挠政赴赵挡拽哉挺括垢拴拾挑垛指垫挣挤拼挖按挥挪拯某甚荆茸革茬荐巷带草茧茵茶荒茫荡荣荤荧故胡荫荔南药标栈柑枯柄栋相查柏栅柳柱柿栏柠树勃要柬咸威歪研砖厘厚砌砂泵砚砍面耐耍牵鸥残殃轴轻鸦皆韭背战点虐临览竖省削尝昧盹是盼眨哇哄哑显冒映星昨咧昭畏趴胃贵界虹虾蚁思蚂虽品咽骂勋哗咱响哈哆咬咳咪哪哟炭峡罚贱贴贻骨幽钙钝钞钟钢钠钥钦钧钩钮卸缸拜看矩毡氢怎牲选适秒香种秋科重复竿段便俩贷顺修俏保促俄俐侮俭俗俘信皇泉鬼侵禹侯追俊盾待徊衍律很须叙剑逃食盆胚胧胆胜胞胖脉胎勉狭狮独狰狡狱狠贸怨急饵饶蚀饺饼峦弯将奖哀亭亮度迹庭疮疯疫疤咨姿亲音帝施闺闻闽阀阁差养美姜叛送类迷籽娄前首逆兹总炼炸烁炮炫烂剃洼洁洪洒柒浇浊洞测洗活派洽染洛浏济洋洲浑浓津恃恒恢恍恬恤恰恼恨举觉宣宦室宫宪突穿窃客诫冠诬语扁袄祖神祝祠误诱诲说诵垦退既屋昼屏屎费陡逊眉孩陨除险院娃姥姨姻娇姚娜怒架贺盈勇怠癸蚤柔垒绑绒结绕骄绘给绚骆络绝绞骇统耕耘耗耙艳泰秦珠班素匿蚕顽盏匪捞栽捕埂捂振载赶起盐捎捍捏埋捉捆捐损袁捌都哲逝捡挫换挽挚热恐捣壶捅埃挨耻耿耽聂恭莽莱莲莫莉荷获晋恶莹莺真框梆桂桔栖档桐株桥桦栓桃格桩校核样根索哥速逗栗贾酌配翅辱唇夏砸砰砾础破原套逐烈殊殉顾轿较顿毙致柴桌虑监紧党逞晒眠晓哮唠鸭晃哺晌剔晕蚌畔蚣蚊蚪蚓哨哩圃哭哦恩鸯唤唁哼唧啊唉唆罢峭峨峰圆峻贼贿赂赃钱钳钻钾铁铃铅缺氧氨特牺造乘敌秤租积秧秩称秘透笔笑笋债借值倚俺倾倒倘俱倡候赁俯倍倦健臭射躬息倔徒徐殷舰舱般航途拿耸爹舀爱豺豹颁颂翁胰脆脂胸胳脏脐胶脑脓逛狸狼卿逢鸵留鸳皱饿馁凌凄恋桨浆衰衷高郭席准座症病疾斋疹疼疲脊效离紊唐瓷资凉站剖竞部旁旅畜阅羞羔瓶拳粉料益兼烤烘烦烧烛烟烙递涛浙涝浦酒涉消涡浩海涂浴浮涣涤流润涧涕浪浸涨烫涩涌悖悟悄悍悔悯悦害宽家宵宴宾窍窄容宰案请朗诸诺读扇诽袜袖袍被祥课冥谁调冤谅谆谈谊剥恳展剧屑弱陵祟陶陷陪娱娟恕娥娘通能难预桑绢绣验继骏球琐理琉琅捧堵措描域捺掩捷排焉掉捶赦堆推埠掀授捻教掏掐掠掂培接掷控探据掘掺职基聆勘聊娶著菱勒黄菲萌萝菌萎菜萄菊菩萍菠萤营乾萧萨菇械彬梦婪梗梧梢梅检梳梯桶梭救曹副票酝酗厢戚硅硕奢盔爽聋袭盛匾雪辅辆颅虚彪雀堂常眶匙晨睁眯眼悬野啪啦曼晦晚啄啡距趾啃跃略蚯蛀蛇唬累鄂唱患啰唾唯啤啥啸崖崎崭逻崔帷崩崇崛婴圈铐铛铝铜铭铲银矫甜秸梨犁秽移笨笼笛笙符第敏做袋悠偿偶偎偷您售停偏躯兜假衅徘徙得衔盘舶船舵斜盒鸽敛悉欲彩领脚脖脯豚脸脱象够逸猜猪猎猫凰猖猛祭馅馆凑减毫烹庶麻庵痊痒痕廊康庸鹿盗章竟商族旋望率阎阐着羚盖眷粘粗粒断剪兽焊焕清添鸿淋涯淹渠渐淑淌混淮淆渊淫渔淘淳液淤淡淀深涮涵婆梁渗情惜惭悼惧惕惟惊惦悴惋惨惯寇寅寄寂宿窒窑密谋谍谎谐袱祷祸谓谚谜逮敢尉屠弹隋堕随蛋隅隆隐婚婶婉颇颈绩绪续骑绰绳维绵绷绸综绽绿缀巢琴琳琢琼斑替揍款堪塔搭堰揩越趁趋超揽堤提博揭喜彭揣插揪搜煮援搀裁搁搓搂搅壹握搔揉斯期欺联葫散惹葬募葛董葡敬葱蒋蒂落韩朝辜葵棒棱棋椰植森焚椅椒棵棍椎棉棚棕棺榔椭惠惑逼粟棘酣酥厨厦硬硝确硫雁殖裂雄颊雳暂雅翘辈悲紫凿辉敞棠赏掌晴睐暑最晰量鼎喷喳晶喇遇喊遏晾景畴践跋跌跑跛遗蛙蛛蜓蜒蛤喝鹃喂喘喉喻啼喧嵌幅帽赋赌赎赐赔黑铸铺链销锁锄锅锈锋锌锐甥掰短智氮毯氯鹅剩稍程稀税筐等筑策筛筒筏答筋筝傲傅牌堡集焦傍储皓皖粤奥街惩御循艇舒逾番释禽腊脾腋腔腕鲁猩猬猾猴惫然馈馋装蛮就敦斌痘痢痪痛童竣阔善翔羡普粪尊奠道遂曾焰港滞湖湘渣渤渺湿温渴溃溅滑湃渝湾渡游滋渲溉愤慌惰愕愣惶愧愉慨割寒富寓窜窝窖窗窘遍雇裕裤裙禅禄谢谣谤谦犀属屡强粥疏隔隙隘媒絮嫂媚婿登缅缆缉缎缓缔缕骗编骚缘瑟鹉瑞瑰瑙魂肆摄摸填搏塌鼓摆携搬摇搞塘摊聘斟蒜勤靴靶鹊蓝墓幕蓬蓄蒲蓉蒙蒸献椿禁楚楷榄想槐榆楼概赖酪酬感碍碘碑碎碰碗碌尴雷零雾雹辐辑输督频龄鉴睛睹睦瞄睫睡睬嗜鄙嗦愚暖盟歇暗暇照畸跨跷跳跺跪路跤跟遣蜈蜗蛾蜂蜕嗅嗡嗓署置罪罩蜀幌错锚锡锣锤锥锦键锯锰矮辞稚稠颓愁筹签简筷毁舅鼠催傻像躲魁衙微愈遥腻腰腥腮腹腺鹏腾腿鲍猿颖触解煞雏馍馏酱禀痹廓痴痰廉靖新韵意誊粮数煎塑慈煤煌满漠滇源滤滥滔溪溜漓滚溢溯滨溶溺粱滩慎誉塞寞窥窟寝谨褂裸福谬群殿辟障媳嫉嫌嫁叠缚缝缠缤剿静碧璃赘熬墙墟嘉摧赫截誓境摘摔撇聚慕暮摹蔓蔑蔡蔗蔽蔼熙蔚兢模槛榴榜榨榕歌遭酵酷酿酸碟碱碳磁愿需辖辗雌裳颗瞅墅嗽踊蜻蜡蝇蜘蝉嘛嘀赚锹锻镀舞舔稳熏箕算箩管箫舆僚僧鼻魄魅貌膜膊膀鲜疑孵馒裹敲豪膏遮腐瘩瘟瘦辣彰竭端旗精粹歉弊熄熔煽潇漆漱漂漫滴漾演漏慢慷寨赛寡察蜜寥谭肇褐褪谱隧嫩翠熊凳骡缩慧撵撕撒撩趣趟撑撮撬播擒墩撞撤增撰聪鞋鞍蕉蕊蔬蕴横槽樱橡樟橄敷豌飘醋醇醉磕磊磅碾震霄霉瞒题暴瞎嘻嘶嘲嘹影踢踏踩踪蝶蝴蝠蝎蝌蝗蝙嘿嘱幢墨镇镐镑靠稽稻黎稿稼箱篓箭篇僵躺僻德艘膝膛鲤鲫熟摩褒瘪瘤瘫凛颜毅糊遵憋潜澎潮潭鲨澳潘澈澜澄懂憔懊憎额翩褥谴鹤憨慰劈履豫缭撼擂操擅燕蕾薯薛薇擎薪薄颠翰噩橱橙橘整融瓢醒霍霎辙冀餐嘴踱蹄蹂蟆螃器噪鹦赠默黔镜赞穆篮篡篷篱儒邀衡膨雕鲸磨瘾瘸凝辨辩糙糖糕燃濒澡激懒憾懈窿壁避缰缴戴擦藉鞠藏藐檬檐檀礁磷霜霞瞭瞧瞬瞳瞩瞪曙蹋蹈螺蟋蟀嚎赡穗魏簧簇繁徽爵朦臊鳄癌辫赢糟糠燥懦豁臀臂翼骤藕鞭藤覆瞻蹦嚣镰翻鳍鹰瀑襟璧戳孽警蘑藻攀曝蹲蹭蹬巅簸簿蟹颤靡癣瓣羹鳖爆疆鬓壤馨耀躁蠕嚼嚷巍籍鳞魔糯灌譬蠢霸露霹躏黯髓赣囊镶瓤罐矗 -------------------------------------------------------------------------------- /resources/font/ALKATIP_Elipbe.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/ALKATIP_Elipbe.ttf -------------------------------------------------------------------------------- /resources/font/ALKATIP_Elipbe_Tom.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/ALKATIP_Elipbe_Tom.ttf -------------------------------------------------------------------------------- /resources/font/FZSTK.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/FZSTK.TTF -------------------------------------------------------------------------------- /resources/font/FranklinGothBookCTT.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/FranklinGothBookCTT.ttf -------------------------------------------------------------------------------- /resources/font/PingFang_A.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/PingFang_A.ttf -------------------------------------------------------------------------------- /resources/font/STHUPO.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/STHUPO.TTF -------------------------------------------------------------------------------- /resources/font/STXINWEI.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/STXINWEI.TTF -------------------------------------------------------------------------------- /resources/font/ZegoeUISemiBold-U_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/ZegoeUISemiBold-U_0.ttf -------------------------------------------------------------------------------- /resources/font/calibri.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/calibri.ttf -------------------------------------------------------------------------------- /resources/font/calibril.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/calibril.ttf -------------------------------------------------------------------------------- /resources/font/fangzheng.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/fangzheng.ttf -------------------------------------------------------------------------------- /resources/font/msyh.ttc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/msyh.ttc -------------------------------------------------------------------------------- /resources/font/msyhbd.ttc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/msyhbd.ttc -------------------------------------------------------------------------------- /resources/font/msyhl.ttc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/msyhl.ttc -------------------------------------------------------------------------------- /resources/font/segoeuisl.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/segoeuisl.ttf -------------------------------------------------------------------------------- /resources/font/youyuan.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/font/youyuan.ttf -------------------------------------------------------------------------------- /resources/markdown/138-13049954.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/138-13049954.jpg -------------------------------------------------------------------------------- /resources/markdown/58.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/58.gif -------------------------------------------------------------------------------- /resources/markdown/6NJ6FU.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/6NJ6FU.jpg -------------------------------------------------------------------------------- /resources/markdown/9nEL.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/9nEL.jpg -------------------------------------------------------------------------------- /resources/markdown/icp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/icp.jpg -------------------------------------------------------------------------------- /resources/markdown/jd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/jd.jpg -------------------------------------------------------------------------------- /resources/markdown/jy_g.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/jy_g.jpg -------------------------------------------------------------------------------- /resources/markdown/jy_o.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/jy_o.jpg -------------------------------------------------------------------------------- /resources/markdown/圪趟照虎.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/圪趟照虎.jpg -------------------------------------------------------------------------------- /resources/markdown/殓蜒细睿.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/殓蜒细睿.jpg -------------------------------------------------------------------------------- /resources/markdown/通疝纽翻.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMYR666/any-captcha/2e15ecd2f2880ebb42836c074e4626da3e8fb720/resources/markdown/通疝纽翻.jpg --------------------------------------------------------------------------------