Use C extension to remove ImageMagick dependency (#40)
This commit is contained in:
parent
9159b8cd10
commit
93ac160201
|
@ -9,6 +9,10 @@
|
||||||
/test/version_tmp/
|
/test/version_tmp/
|
||||||
/tmp/
|
/tmp/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.bundle
|
||||||
|
*.o
|
||||||
|
ext/rucaptcha/Makefile
|
||||||
|
ext/rucaptcha/*.gif
|
||||||
|
|
||||||
## RubyMine Ide files
|
## RubyMine Ide files
|
||||||
.idea/
|
.idea/
|
||||||
|
|
|
@ -3,8 +3,5 @@ rvm:
|
||||||
- 2.2.3
|
- 2.2.3
|
||||||
services:
|
services:
|
||||||
- memcached
|
- memcached
|
||||||
addons:
|
script:
|
||||||
apt:
|
- bundle exec rake compile && bundle exec rake
|
||||||
packages:
|
|
||||||
- imagemagick
|
|
||||||
- tesseract-ocr
|
|
||||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,3 +1,15 @@
|
||||||
|
2.0.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
*Break Changes!*
|
||||||
|
|
||||||
|
WARNING!: This version have so many break changes!
|
||||||
|
|
||||||
|
- Use C ext instead of ImageMagick, now it's no dependencies!
|
||||||
|
- New captcha style.
|
||||||
|
- Remove `len`, `font_size`, `cache_limit` config key, no support now.
|
||||||
|
- Output `GIF` format.
|
||||||
|
|
||||||
1.2.0
|
1.2.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
rucaptcha (1.2.0)
|
rucaptcha (2.0.0)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
|
@ -96,6 +96,8 @@ GEM
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rake (11.3.0)
|
rake (11.3.0)
|
||||||
|
rake-compiler (1.0.3)
|
||||||
|
rake
|
||||||
rspec (3.3.0)
|
rspec (3.3.0)
|
||||||
rspec-core (~> 3.3.0)
|
rspec-core (~> 3.3.0)
|
||||||
rspec-expectations (~> 3.3.0)
|
rspec-expectations (~> 3.3.0)
|
||||||
|
@ -135,8 +137,9 @@ DEPENDENCIES
|
||||||
dalli
|
dalli
|
||||||
rails
|
rails
|
||||||
rake
|
rake
|
||||||
|
rake-compiler (~> 1)
|
||||||
rspec
|
rspec
|
||||||
rucaptcha!
|
rucaptcha!
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.13.6
|
1.13.7
|
||||||
|
|
45
README.md
45
README.md
|
@ -4,44 +4,20 @@
|
||||||
[![Build Status](https://travis-ci.org/huacnlee/rucaptcha.svg)](https://travis-ci.org/huacnlee/rucaptcha)
|
[![Build Status](https://travis-ci.org/huacnlee/rucaptcha.svg)](https://travis-ci.org/huacnlee/rucaptcha)
|
||||||
[![Code Climate](https://codeclimate.com/github/huacnlee/rucaptcha/badges/gpa.svg)](https://codeclimate.com/github/huacnlee/rucaptcha)
|
[![Code Climate](https://codeclimate.com/github/huacnlee/rucaptcha/badges/gpa.svg)](https://codeclimate.com/github/huacnlee/rucaptcha)
|
||||||
|
|
||||||
This is a Captcha gem for Rails Applications. It runs an ImageMagick command to draw Captcha image - so it has NO performance issues or memory leak issues. **There is NO: RMagick**
|
This is a Captcha gem for Rails Applications. It drawing captcha image with C code.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
![1](https://cloud.githubusercontent.com/assets/5518/15423974/b186b0d6-1eb2-11e6-9c0e-4cc3a66f32c8.png)
|
<img src="https://cloud.githubusercontent.com/assets/5518/22151425/e02390c8-df58-11e6-974d-5eb9b1a4e577.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151427/e4939d92-df58-11e6-9754-4a46a86acea8.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151431/e494576e-df58-11e6-9845-a5590904c175.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151432/e495066e-df58-11e6-92b8-38b40b73aba0.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151428/e49404ee-df58-11e6-8e2d-8b17b33a3710.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151430/e4942406-df58-11e6-9ff8-6e2325304b41.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151429/e4941ae2-df58-11e6-8107-757296573b2f.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151433/e4c7c89c-df58-11e6-9853-1ffbb4986962.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151435/e4c97ea8-df58-11e6-8959-b4c78716271d.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151436/e4cc09f2-df58-11e6-965c-673333b33c0d.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151434/e4c87788-df58-11e6-9490-c255aaafce71.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151445/ee35ff66-df58-11e6-8660-a3673ef3f5ee.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151446/ee67b074-df58-11e6-9b95-7d53eec21c33.gif" width="150px" />
|
||||||
![2](https://cloud.githubusercontent.com/assets/5518/15423975/b1887b6e-1eb2-11e6-895f-5629f82697d3.png)
|
|
||||||
![3](https://cloud.githubusercontent.com/assets/5518/15423978/b18f08ee-1eb2-11e6-9670-c21dba290e04.png)
|
|
||||||
![4](https://cloud.githubusercontent.com/assets/5518/15423976/b18b6946-1eb2-11e6-8413-700ded157262.png)
|
|
||||||
![5](https://cloud.githubusercontent.com/assets/5518/15423977/b18e7c62-1eb2-11e6-96f7-5bd6981d4185.png)
|
|
||||||
![6](https://cloud.githubusercontent.com/assets/5518/15423979/b19175d4-1eb2-11e6-9417-7d496fb996b4.png)
|
|
||||||
![7](https://cloud.githubusercontent.com/assets/5518/15423980/b1caf944-1eb2-11e6-862e-78c0a9360b43.png)
|
|
||||||
|
|
||||||
Idea by: https://ruby-china.org/topics/20558#reply4
|
|
||||||
|
|
||||||
[中文介绍和使用说明](https://ruby-china.org/topics/27832)
|
[中文介绍和使用说明](https://ruby-china.org/topics/27832)
|
||||||
|
|
||||||
## Feature
|
## Feature
|
||||||
|
|
||||||
- Only need `ImageMagick`, No `RMagick`, No `mini_magick`;
|
- No dependencies. No ImageMagick, No RMagick.
|
||||||
- For Rails Application;
|
- For Rails Application;
|
||||||
- Simple, Easy to use;
|
- Simple, Easy to use;
|
||||||
- File Caching for performance.
|
- High performance.
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
- ImageMagick 6.9+
|
|
||||||
|
|
||||||
#### Ubuntu
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo apt-get install imagemagick ghostscript
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Mac OS X
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew install imagemagick ghostscript
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -55,17 +31,10 @@ Create `config/initializers/rucaptcha.rb`
|
||||||
|
|
||||||
```rb
|
```rb
|
||||||
RuCaptcha.configure do
|
RuCaptcha.configure do
|
||||||
# Number of chars, default: 4
|
|
||||||
self.len = 4
|
|
||||||
# Image font size, default: 45
|
|
||||||
self.font_size = 45
|
|
||||||
# Cache generated images in file store, this is config files limit, default: 100
|
|
||||||
# set 0 to disable file cache.
|
|
||||||
self.cache_limit = 100
|
|
||||||
# Custom captcha code expire time if you need, default: 2 minutes
|
|
||||||
# self.expires_in = 120
|
|
||||||
# Color style, default: :colorful, allows: [:colorful, :black_white]
|
# Color style, default: :colorful, allows: [:colorful, :black_white]
|
||||||
# self.style = :colorful
|
# self.style = :colorful
|
||||||
|
# Custom captcha code expire time if you need, default: 2 minutes
|
||||||
|
# self.expires_in = 120
|
||||||
# [Requirement]
|
# [Requirement]
|
||||||
# Store Captcha code where, this config more like Rails config.cache_store
|
# Store Captcha code where, this config more like Rails config.cache_store
|
||||||
# default: Rails application config.cache_store
|
# default: Rails application config.cache_store
|
||||||
|
@ -99,7 +68,7 @@ class AccountController < ApplicationController
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
> TIP: Sometime you may need keep last verified captcha code in session on `verify_rucaptcha?` method call, you can use `keep_session: true`. For example: ` Verify_rucaptcha? (@user, keep_session: true) `.
|
> TIP: Sometime you may need keep last verified captcha code in session on `verify_rucaptcha?` method call, you can use `keep_session: true`. For example: `verify_rucaptcha? @user, keep_session: true`.
|
||||||
|
|
||||||
View `app/views/account/new.html.erb`
|
View `app/views/account/new.html.erb`
|
||||||
|
|
||||||
|
|
13
Rakefile
13
Rakefile
|
@ -1,5 +1,18 @@
|
||||||
require "bundler/gem_tasks"
|
require "bundler/gem_tasks"
|
||||||
require "rspec/core/rake_task"
|
require "rspec/core/rake_task"
|
||||||
|
require 'rake/extensiontask'
|
||||||
|
|
||||||
|
Rake::ExtensionTask.new "rucaptcha" do |ext|
|
||||||
|
ext.lib_dir = "lib/rucaptcha"
|
||||||
|
end
|
||||||
|
|
||||||
RSpec::Core::RakeTask.new(:spec)
|
RSpec::Core::RakeTask.new(:spec)
|
||||||
task default: :spec
|
task default: :spec
|
||||||
|
|
||||||
|
|
||||||
|
task :preview do
|
||||||
|
require 'rucaptcha'
|
||||||
|
|
||||||
|
res = RuCaptcha.create(1)
|
||||||
|
puts res[1]
|
||||||
|
end
|
|
@ -3,11 +3,13 @@ module RuCaptcha
|
||||||
def index
|
def index
|
||||||
headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
|
headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
|
||||||
headers['Pragma'] = 'no-cache'
|
headers['Pragma'] = 'no-cache'
|
||||||
|
data = generate_rucaptcha
|
||||||
|
opts = { disposition: 'inline', type: 'image/gif' }
|
||||||
|
|
||||||
if Gem.win_platform?
|
if Gem.win_platform?
|
||||||
send_file generate_rucaptcha, disposition: 'inline', type: 'image/png'
|
send_file data, opts
|
||||||
else
|
else
|
||||||
send_data generate_rucaptcha, disposition: 'inline', type: 'image/png'
|
send_data data, opts
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,345 @@
|
||||||
|
// Colors from
|
||||||
|
// https://material.io/guidelines/style/color.html#color-ui-color-palette
|
||||||
|
static char *colors[] = {
|
||||||
|
// Black 500 #000000
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\x11\x11\x11"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Red 500 #F44336
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xF4\x43\x36"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Pink 500 #E91E63
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xE9\x1E\x63"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Purple 500 #9C27B0
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\x9C\x27\xB0"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Deep Purple 500 #673AB7
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\x67\x3A\xB7"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Indigo 500 #3F51B5
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\x3F\x51\xB5"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Blue 500 #2196F3
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\x21\x96\xF3"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Light Blue 500 #03A9F4
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\x03\xA9\xF4"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Cyan 500 #00BCD4
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\x00\xBC\xD4"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Teal 500 #009688
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\x00\x96\x88"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Green 500 #4CAF50
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\x4C\xAF\x50"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Light Green 500 #8BC34A
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\x8B\xC3\x4A"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Lime 500 #CDDC39
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xCD\xDC\x39"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Yellow 500 #FFEB3B
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xFF\xEB\x3B"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Amber 500 #FFC107
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xFF\xC1\x07"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Orange 500 #FF9800
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xFF\x98\x00"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Deep Orange 500 #FF5722
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xFF\x57\x22"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
|
||||||
|
|
||||||
|
// Brown 500 #795548
|
||||||
|
"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\x79\x55\x48"
|
||||||
|
"\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04"
|
||||||
|
};
|
|
@ -0,0 +1,2 @@
|
||||||
|
require 'mkmf'
|
||||||
|
create_makefile('rucaptcha/rucaptcha')
|
|
@ -0,0 +1,27 @@
|
||||||
|
static int8_t lt0[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-4,11,7,5,3,1,0,0,0,1,3,7,13,-100,-2,11,3,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-1,7,0,0,0,0,0,0,3,9,11,9,3,0,0,0,0,13,-100,9,0,0,0,0,0,0,3,-5,3,0,0,0,7,-100,5,0,0,0,0,0,1,13,-5,9,0,0,0,1,-100,7,0,0,0,0,1,13,-6,13,0,0,0,0,-100,-1,9,1,0,5,13,-8,0,0,0,0,13,-100,-14,0,0,0,0,11,-100,-14,0,0,0,0,11,-100,-14,0,0,0,0,11,-100,-12,13,5,0,0,0,0,11,-100,-8,13,9,5,1,0,0,0,0,0,0,11,-100,-4,13,7,3,1,0,0,0,0,1,1,0,0,0,0,11,-100,-2,13,5,0,0,0,0,0,5,9,13,-2,0,0,0,0,11,-100,-1,13,1,0,0,0,0,7,-6,0,0,0,0,11,-100,13,1,0,0,0,0,13,-7,0,0,0,0,11,-100,5,0,0,0,0,5,-8,0,0,0,0,11,-100,0,0,0,0,0,11,-8,0,0,0,0,11,-100,0,0,0,0,0,13,-7,13,0,0,0,0,11,-100,1,0,0,0,0,-7,9,0,0,0,0,0,9,-3,9,-100,5,0,0,0,0,3,13,-3,11,3,0,0,0,0,0,0,0,9,13,3,5,-100,13,0,0,0,0,0,0,1,1,0,0,0,1,11,9,0,0,0,0,0,0,1,13,-100,-1,11,1,0,0,0,0,0,0,0,0,5,-3,9,0,0,0,0,0,11,-100,-2,13,7,3,0,0,0,3,7,13,-5,9,0,1,3,9,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt1[]={-100,-100,-4,13,5,0,3,-100,-3,11,1,0,0,0,7,-100,-2,7,0,0,0,0,0,3,-100,13,3,0,0,0,0,0,0,5,-100,1,0,0,0,0,0,0,0,9,-100,1,0,0,0,0,0,0,0,13,-100,13,3,0,0,0,0,0,1,-100,-2,5,0,0,0,0,5,-100,-3,0,0,0,0,9,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,9,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,3,13,9,5,3,1,0,0,1,3,5,9,-100,-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,13,-100,-3,0,0,0,0,0,5,13,-2,13,11,9,5,0,0,0,0,1,13,-100,-3,0,0,0,0,1,-8,13,1,0,0,0,5,-100,-3,3,0,0,0,5,-9,13,0,0,0,0,11,-100,-3,0,0,0,0,9,-10,7,0,0,0,5,-100,-3,1,0,0,0,11,-10,13,0,0,0,0,-100,-3,3,0,0,0,11,-11,3,0,0,0,11,-100,-3,1,0,0,0,11,-11,7,0,0,0,7,-100,-3,0,0,0,0,11,-11,9,0,0,0,3,-100,-3,0,0,0,0,11,-11,11,0,0,0,1,-100,-3,0,0,0,0,11,-11,11,0,0,0,1,-100,-3,0,0,0,0,11,-11,11,0,0,0,0,-100,-3,0,0,0,0,11,-11,9,0,0,0,0,-100,-3,0,0,0,0,11,-11,7,0,0,0,3,-100,-3,0,0,0,0,11,-11,3,0,0,0,7,-100,-3,0,0,0,0,11,-11,0,0,0,0,11,-100,-3,0,0,0,0,11,-10,9,0,0,0,3,-100,-3,0,0,0,0,9,-10,3,0,0,0,11,-100,-3,0,0,0,0,3,-9,11,0,0,0,5,-100,-2,13,0,0,0,0,0,9,-7,11,1,0,0,3,-100,-2,7,0,0,0,0,0,0,7,13,-2,13,9,3,0,0,0,3,13,-100,-2,13,0,0,5,13,11,1,0,0,0,0,0,0,0,0,0,7,-100,-3,9,11,-4,7,3,1,0,0,1,5,9,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt2[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,13,7,3,1,0,0,1,3,7,13,-100,-5,9,0,0,0,0,0,0,0,0,0,0,5,13,-100,-3,13,3,0,0,0,5,13,13,7,0,0,0,0,0,1,13,-100,-2,13,1,0,0,0,9,-4,7,0,0,0,0,0,1,-100,-1,13,1,0,0,0,9,-6,5,0,0,0,0,0,13,-100,-1,5,0,0,0,3,-8,1,0,0,0,3,-100,13,0,0,0,0,11,-8,13,3,0,3,-100,7,0,0,0,1,-100,5,0,0,0,5,-100,3,0,0,0,9,-100,1,0,0,0,11,-100,0,0,0,0,11,-100,0,0,0,0,11,-100,0,0,0,0,11,-100,0,0,0,0,9,-100,1,0,0,0,5,-100,5,0,0,0,0,13,-100,11,0,0,0,0,7,-100,-1,3,0,0,0,0,13,-100,-1,11,0,0,0,0,3,-12,9,-100,-2,7,0,0,0,0,3,13,-8,9,1,3,-100,-3,5,0,0,0,0,1,9,-5,9,3,0,0,11,-100,-4,5,0,0,0,0,0,0,1,1,1,0,0,0,0,11,-100,-5,9,1,0,0,0,0,0,0,0,0,0,3,13,-100,-7,11,7,3,1,0,1,3,7,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt3[]={-100,-100,-100,-100,-18,11,3,0,-100,-16,13,3,0,0,0,-100,-14,9,3,0,0,0,0,0,-100,-13,3,0,0,0,0,0,0,0,-100,-13,0,0,0,0,0,0,0,0,-100,-13,9,1,0,0,0,0,0,0,-100,-15,13,5,0,0,0,0,-100,-17,1,0,0,0,-100,-17,3,0,0,0,-100,-17,1,0,0,0,-100,-17,0,0,0,0,-100,-16,13,0,0,0,0,-100,-16,13,0,0,0,0,-100,-6,11,5,3,1,0,0,1,5,9,13,13,0,0,0,0,-100,-4,13,3,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,-100,-3,13,1,0,0,0,0,5,11,-1,13,11,3,0,0,0,0,0,0,-100,-2,13,1,0,0,0,0,7,-6,11,0,0,0,0,0,-100,-2,3,0,0,0,0,9,-8,11,0,0,0,0,-100,-1,9,0,0,0,0,7,-9,11,0,0,0,0,-100,-1,1,0,0,0,0,13,-9,11,0,0,0,0,-100,11,0,0,0,0,3,-10,11,0,0,0,0,-100,5,0,0,0,0,13,-10,11,0,0,0,0,-100,3,0,0,0,3,-11,11,0,0,0,0,-100,0,0,0,0,7,-11,11,0,0,0,0,-100,0,0,0,0,11,-11,11,0,0,0,0,-100,0,0,0,0,11,-11,11,0,0,0,0,-100,0,0,0,0,11,-11,11,0,0,0,0,-100,1,0,0,0,9,-11,11,0,0,0,0,-100,3,0,0,0,7,-11,11,0,0,0,0,-100,7,0,0,0,3,-11,11,0,0,0,0,-100,13,0,0,0,0,13,-10,13,0,0,0,0,-100,-1,3,0,0,0,5,-11,0,0,0,0,-100,-1,13,0,0,0,0,11,-10,0,0,0,0,-100,-2,7,0,0,0,1,13,-8,13,0,0,0,0,13,-100,-3,5,0,0,0,1,11,-7,5,0,0,0,0,9,-100,-4,5,0,0,0,0,3,9,13,-1,13,11,1,0,0,0,0,0,0,0,5,-100,-5,9,1,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,13,-100,-7,9,3,1,0,0,3,7,13,-1,11,1,0,1,5,7,11,-100,-18,13,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt4[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-7,13,5,1,1,0,1,3,9,13,-100,-6,5,0,0,0,0,0,0,0,0,0,9,-100,-4,11,1,0,0,3,11,-1,13,7,1,0,0,0,9,-100,-3,9,0,0,0,1,13,-5,3,0,0,1,-100,-2,9,0,0,0,0,13,-6,11,0,0,0,9,-100,-1,13,0,0,0,0,9,-8,0,0,0,1,-100,-1,5,0,0,0,0,13,-8,3,0,0,0,11,-100,-1,0,0,0,0,0,-8,13,1,0,0,0,5,-100,9,0,0,0,0,0,3,11,-4,13,11,1,0,0,0,0,1,-100,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,-100,1,0,0,0,1,13,-100,0,0,0,0,11,-100,0,0,0,0,11,-100,1,0,0,0,9,-100,3,0,0,0,7,-100,7,0,0,0,5,-100,13,0,0,0,0,11,-100,-1,5,0,0,0,1,13,-100,-1,13,1,0,0,0,1,13,-10,13,11,-100,-2,11,0,0,0,0,1,13,-8,13,1,1,-100,-3,11,0,0,0,0,0,7,13,-4,11,7,0,0,9,-100,-4,11,1,0,0,0,0,0,1,1,1,0,0,0,0,7,-100,-5,13,5,0,0,0,0,0,0,0,0,0,1,9,-100,-7,13,7,3,0,0,0,1,5,9,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt5[]={-100,-100,-100,-100,-9,13,9,3,1,0,1,5,13,-100,-8,7,0,0,0,0,0,0,0,3,-100,-7,3,0,0,0,0,0,0,0,0,1,-100,-6,5,0,0,0,0,0,0,0,0,0,3,-100,-5,13,0,0,3,13,9,1,0,0,0,0,11,-100,-5,9,0,0,13,-2,13,5,0,1,9,-100,-5,5,0,0,-100,-5,1,0,1,-100,-5,1,0,0,-100,-5,0,0,0,-100,-5,0,0,0,13,-100,-5,0,0,0,9,-100,-5,0,0,0,7,-100,-5,0,0,0,5,-100,-3,13,7,0,0,0,0,9,-1,13,11,13,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-1,11,13,-1,7,0,0,0,0,5,-1,13,11,13,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,7,-100,-3,13,5,0,0,0,0,0,7,13,-100,-1,5,0,0,0,0,0,0,0,0,0,0,0,1,11,-100,-1,7,1,0,0,0,0,0,0,0,0,1,3,7,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt6[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-7,11,7,3,1,0,0,1,3,7,13,-4,13,7,5,7,11,-100,-5,11,3,0,0,0,0,0,0,0,0,0,0,5,13,13,5,0,0,0,0,0,-100,-4,9,0,0,0,5,13,-1,13,9,3,0,0,0,0,0,0,0,0,0,0,0,1,-100,-3,11,0,0,0,5,-6,5,0,0,0,0,0,11,13,9,3,0,9,-100,-2,13,0,0,0,0,13,-7,1,0,0,0,0,13,-100,-2,1,0,0,0,7,-8,7,0,0,0,0,7,-100,-2,0,0,0,0,9,-8,11,0,0,0,0,3,-100,-2,0,0,0,0,11,-9,0,0,0,0,1,-100,-2,0,0,0,0,11,-9,0,0,0,0,0,-100,-2,0,0,0,0,9,-8,13,0,0,0,0,1,-100,-2,3,0,0,0,5,-8,9,0,0,0,0,7,-100,-2,13,1,0,0,0,13,-7,5,0,0,0,0,13,-100,-3,11,0,0,0,3,13,-5,7,0,0,0,0,11,-100,-4,7,0,0,0,1,9,13,-1,13,7,0,0,0,1,11,-100,-4,13,0,0,0,0,0,0,0,0,0,0,0,5,13,-100,-4,13,0,0,0,0,0,0,1,3,5,9,-100,-2,13,5,0,11,-100,-1,13,1,0,0,-100,-1,3,0,0,0,1,7,13,-100,-1,0,0,0,0,0,0,0,1,3,7,9,11,13,-100,-1,5,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,11,-100,-2,11,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,11,-100,-4,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-3,9,1,0,3,9,13,13,11,7,3,0,0,0,0,0,0,0,0,0,13,-100,-1,7,1,0,0,9,-8,11,7,3,0,0,0,0,0,5,-100,9,0,0,0,3,-13,11,1,0,0,1,-100,1,0,0,0,9,-15,0,0,0,-100,0,0,0,0,9,-14,13,0,0,1,-100,3,0,0,0,1,-14,7,0,0,5,-100,11,0,0,0,0,5,-12,11,0,0,0,13,-100,-1,11,1,0,0,0,1,7,11,13,-1,13,13,11,9,5,3,1,0,0,3,13,-100,-3,9,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,9,-100,-6,9,7,3,1,1,0,0,1,1,3,7,11,-100,-101};
|
||||||
|
static int8_t lt7[]={-100,-100,-100,-100,-4,13,7,1,9,-100,-2,13,7,0,0,0,3,-100,-1,7,0,0,0,0,0,5,-100,1,0,0,0,0,0,0,7,-100,3,0,0,0,0,0,0,7,-100,13,7,0,0,0,0,0,9,-100,-2,5,0,0,0,0,9,-100,-2,11,0,0,0,0,9,-100,-3,0,0,0,0,9,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-5,11,5,1,0,1,7,-100,-3,0,0,0,0,11,-3,13,3,0,0,0,0,0,0,3,-100,-3,0,0,0,0,11,-2,7,0,0,0,0,0,0,0,0,0,9,-100,-3,0,0,0,0,11,11,3,0,5,11,-1,13,9,1,0,0,0,3,-100,-3,0,0,0,0,3,0,1,11,-6,1,0,0,0,13,-100,-3,0,0,0,0,0,5,-8,11,0,0,0,11,-100,-3,0,0,0,0,11,-10,0,0,0,7,-100,-3,0,0,0,0,13,-10,0,0,0,7,-100,-3,0,0,0,0,11,-10,0,0,0,7,-100,-3,0,0,0,0,11,-10,0,0,0,7,-100,-3,0,0,0,0,13,-10,0,0,0,9,-100,-3,0,0,0,0,13,-10,0,0,0,9,-100,-3,0,0,0,0,-11,0,0,0,11,-100,-3,0,0,0,1,-11,0,0,0,13,-100,-3,0,0,0,1,-11,0,0,0,13,-100,-3,0,0,0,3,-11,0,0,0,-100,-3,0,0,0,3,-11,0,0,0,-100,-3,0,0,0,3,-11,0,0,0,-100,-3,0,0,0,3,-10,13,0,0,0,13,-100,-3,0,0,0,1,-10,13,0,0,0,11,-100,-2,9,0,0,0,0,-10,11,0,0,0,5,-100,-1,7,0,0,0,0,0,5,13,-7,13,3,0,0,0,0,7,-100,5,0,0,0,0,0,0,0,0,3,-5,1,0,0,0,0,0,0,1,3,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt8[]={-100,-100,-100,-100,-3,5,1,0,3,11,-100,-2,7,0,0,0,0,0,11,-100,-2,1,0,0,0,0,0,5,-100,-2,0,0,0,0,0,0,5,-100,-2,5,0,0,0,0,0,11,-100,-3,7,0,0,3,9,-100,-4,13,-100,-100,-100,-100,-100,-100,-100,-4,11,3,0,9,-100,-2,9,3,0,0,0,9,-100,11,1,0,0,0,0,0,7,-100,1,0,0,0,0,0,0,7,-100,1,0,0,0,0,0,0,9,-100,-1,11,0,0,0,0,0,9,-100,-2,7,0,0,0,0,11,-100,-3,0,0,0,0,13,-100,-3,1,0,0,0,-100,-3,1,0,0,0,13,-100,-3,1,0,0,0,13,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-2,13,0,0,0,0,7,-100,-2,13,0,0,0,0,1,-100,-2,7,0,0,0,0,0,9,-100,7,0,0,0,0,0,0,0,0,3,-100,9,5,1,1,0,0,1,1,3,5,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt9[]={-100,-100,-100,-100,-6,5,0,1,5,13,-100,-5,5,0,0,0,0,1,-100,-5,1,0,0,0,0,0,13,-100,-5,0,0,0,0,0,0,-100,-5,5,0,0,0,0,3,-100,-6,7,1,0,5,13,-100,-100,-100,-100,-100,-100,-100,-100,-6,13,7,3,0,13,-100,-5,7,0,0,0,0,11,-100,-3,7,1,0,0,0,0,0,11,-100,-2,13,0,0,0,0,0,0,0,11,-100,-3,11,3,0,0,0,0,0,11,-100,-5,9,0,0,0,0,11,-100,-6,1,0,0,0,11,-100,-6,3,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,3,0,0,0,11,-100,-6,3,0,0,0,11,-100,-6,1,0,0,0,11,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,-100,-6,1,0,0,0,-100,-6,1,0,0,1,-100,-6,1,0,0,3,-100,-6,0,0,0,5,-100,-6,0,0,0,7,-100,-6,0,0,0,11,-100,11,0,0,0,5,5,0,0,5,-100,3,0,0,0,0,0,0,3,-100,0,0,0,0,0,0,0,13,-100,1,0,0,0,0,0,11,-100,13,3,0,0,3,11,-100,-100,-101};
|
||||||
|
static int8_t lt10[]={-100,-100,-100,-100,-6,9,1,13,-100,-3,13,5,0,0,0,11,-100,-1,13,5,0,0,0,0,0,11,-100,13,1,0,0,0,0,0,0,11,-100,3,0,0,0,0,0,0,0,11,-100,11,3,0,0,0,0,0,0,11,-100,-2,13,0,0,0,0,0,11,-100,-3,9,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-7,3,0,0,0,0,0,0,0,0,0,3,-100,-4,0,0,0,0,11,-7,5,0,0,0,0,0,0,0,1,7,13,-100,-4,0,0,0,0,11,-8,9,0,0,0,1,9,-100,-4,0,0,0,0,11,-7,13,1,0,0,7,-100,-4,0,0,0,0,11,-7,5,0,3,13,-100,-4,0,0,0,0,11,-6,5,0,5,-100,-4,0,0,0,0,11,-5,5,1,11,-100,-4,0,0,0,0,11,-3,11,3,1,-100,-4,0,0,0,0,11,-1,11,3,0,0,1,-100,-4,0,0,0,0,11,9,0,0,0,0,0,11,-100,-4,0,0,0,0,0,0,1,0,0,0,0,3,-100,-4,0,0,0,0,0,9,-1,11,1,0,0,0,9,-100,-4,0,0,0,0,5,-4,3,0,0,0,11,-100,-4,0,0,0,0,11,-4,13,1,0,0,0,13,-100,-4,0,0,0,0,11,-5,11,0,0,0,1,13,-100,-4,0,0,0,0,11,-6,3,0,0,0,3,-100,-4,0,0,0,0,11,-6,11,0,0,0,0,7,-100,-4,0,0,0,0,11,-7,3,0,0,0,0,7,-100,-3,13,0,0,0,0,11,-7,13,0,0,0,0,0,7,-100,-2,13,3,0,0,0,0,7,-7,9,0,0,0,0,0,0,3,11,-100,-1,1,0,0,0,0,0,0,0,0,1,3,-4,0,0,0,0,0,0,0,0,0,0,3,-100,-1,7,1,0,0,0,0,0,0,0,0,7,-4,3,0,0,0,0,0,0,1,1,5,9,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt11[]={-100,-100,-100,-6,11,7,11,-100,-4,11,3,0,0,5,-100,-3,5,0,0,0,0,5,-100,-1,11,1,0,0,0,0,0,7,-100,7,0,0,0,0,0,0,0,7,-100,0,0,0,0,0,0,0,0,9,-100,7,0,0,0,0,0,0,0,9,-100,-2,9,1,0,0,0,0,9,-100,-3,11,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,7,-100,-3,5,0,0,0,0,0,13,-100,-1,9,1,0,0,0,0,0,0,0,1,9,-100,-1,5,1,0,0,0,0,0,0,0,1,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt12[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-5,11,5,0,-21,7,1,0,3,9,-100,-4,7,0,0,0,13,-4,11,5,1,1,0,1,7,-7,11,3,0,0,0,0,0,5,-100,-2,11,1,0,0,0,0,11,-2,9,1,0,0,0,0,0,0,0,9,-4,13,5,0,0,0,0,0,0,0,0,7,-100,13,3,0,0,0,0,0,0,7,13,3,0,0,0,1,0,0,0,0,0,0,7,-1,13,7,0,0,0,0,0,0,0,0,0,0,0,11,-100,3,0,0,0,0,0,0,0,1,0,0,5,11,-3,11,0,0,0,0,0,0,0,3,9,13,13,-3,7,0,0,0,0,5,-100,13,3,0,0,0,0,0,0,0,7,13,-6,3,0,0,0,0,0,9,-8,5,0,0,0,1,-100,-2,11,0,0,0,0,0,3,-8,9,0,0,0,0,7,-9,11,0,0,0,0,-100,-3,3,0,0,0,0,7,-8,13,0,0,0,0,-10,11,0,0,0,0,-100,-3,7,0,0,0,0,11,-9,0,0,0,0,-10,11,0,0,0,1,-100,-3,11,0,0,0,0,11,-9,0,0,0,0,-10,11,0,0,0,3,-100,-3,13,0,0,0,0,11,-8,13,0,0,0,0,-10,11,0,0,0,5,-100,-3,13,0,0,0,0,11,-8,11,0,0,0,0,-10,11,0,0,0,5,-100,-4,0,0,0,0,13,-8,9,0,0,0,0,-10,11,0,0,0,5,-100,-4,0,0,0,0,13,-8,11,0,0,0,0,-10,11,0,0,0,3,-100,-4,0,0,0,0,13,-8,11,0,0,0,0,-10,11,0,0,0,0,-100,-3,13,0,0,0,1,-9,13,0,0,0,0,-10,11,0,0,0,0,-100,-3,11,0,0,0,13,-10,0,0,0,0,-10,11,0,0,0,0,-100,-4,0,0,0,11,-10,0,0,0,0,-10,11,0,0,0,0,-100,-3,13,0,0,0,3,-9,13,0,0,0,0,13,-9,9,0,0,0,0,-100,-3,7,0,0,0,0,13,-8,11,0,0,0,0,11,-9,7,0,0,0,0,13,-100,-3,3,0,0,0,0,9,-8,5,0,0,0,0,5,-9,5,0,0,0,0,7,-100,-1,13,3,0,0,0,0,0,1,11,-6,9,0,0,0,0,0,0,3,-7,11,1,0,0,0,0,1,13,-100,11,0,0,0,0,0,0,0,0,0,3,-4,3,0,0,0,0,0,0,0,0,5,-5,1,0,0,0,0,0,0,0,0,9,-100,13,1,0,0,0,0,0,0,0,1,9,-4,1,0,0,0,0,0,0,0,1,5,-5,1,0,0,0,0,0,0,0,0,7,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt13[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-3,13,7,3,0,13,-5,13,7,1,0,0,3,7,-100,-2,5,0,0,0,0,-4,13,3,0,0,0,0,0,0,0,7,-100,7,1,0,0,0,0,0,-3,7,0,0,0,0,0,0,0,0,0,0,13,-100,1,0,0,0,0,0,0,13,9,1,0,5,11,13,-1,11,3,0,0,0,0,9,-100,13,3,0,0,0,0,0,1,1,7,-7,3,0,0,0,3,-100,-2,1,0,0,0,0,7,-9,13,0,0,0,1,-100,-2,7,0,0,0,0,-11,1,0,0,0,-100,-2,9,0,0,0,0,-11,1,0,0,0,13,-100,-2,11,0,0,0,0,-11,3,0,0,0,13,-100,-2,11,0,0,0,0,-11,5,0,0,0,11,-100,-2,11,0,0,0,0,-11,3,0,0,0,11,-100,-2,11,0,0,0,0,-11,1,0,0,0,11,-100,-2,11,0,0,0,0,-11,0,0,0,0,11,-100,-2,11,0,0,0,0,-11,0,0,0,0,11,-100,-2,11,0,0,0,0,-11,1,0,0,0,11,-100,-2,11,0,0,0,0,-11,3,0,0,0,11,-100,-2,11,0,0,0,0,-11,3,0,0,0,11,-100,-2,11,0,0,0,0,13,-10,5,0,0,0,11,-100,-2,11,0,0,0,0,13,-10,5,0,0,0,11,-100,-2,11,0,0,0,0,9,-10,5,0,0,0,9,-100,-2,7,0,0,0,0,5,-10,3,0,0,0,7,-100,-1,13,1,0,0,0,0,1,11,-7,11,5,0,0,0,0,0,3,9,-100,-1,1,0,0,0,0,0,0,0,0,3,-4,3,0,0,0,0,0,0,0,0,0,3,-100,-1,0,0,0,0,0,0,0,0,0,3,-4,5,1,0,0,0,0,0,0,0,0,1,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt14[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-7,13,7,3,1,0,0,1,5,9,-100,-6,7,0,0,0,0,0,0,0,0,0,1,7,-100,-4,11,1,0,0,1,9,13,-1,13,11,5,0,0,0,3,13,-100,-3,11,0,0,0,3,13,-6,13,1,0,0,0,13,-100,-2,11,0,0,0,1,13,-8,13,0,0,0,5,-100,-2,0,0,0,0,9,-10,5,0,0,0,11,-100,-1,7,0,0,0,1,-11,13,0,0,0,1,-100,-1,1,0,0,0,5,-12,1,0,0,0,9,-100,11,0,0,0,0,11,-12,5,0,0,0,3,-100,7,0,0,0,0,13,-12,9,0,0,0,0,-100,3,0,0,0,0,13,-12,11,0,0,0,0,-100,1,0,0,0,0,-13,11,0,0,0,1,-100,0,0,0,0,0,-13,11,0,0,0,1,-100,0,0,0,0,0,13,-12,11,0,0,0,0,-100,1,0,0,0,0,13,-12,9,0,0,0,1,-100,5,0,0,0,0,11,-12,5,0,0,0,3,-100,9,0,0,0,0,9,-12,3,0,0,0,7,-100,-1,1,0,0,0,5,-12,0,0,0,0,11,-100,-1,9,0,0,0,3,-11,13,0,0,0,3,-100,-2,3,0,0,0,13,-10,7,0,0,0,11,-100,-2,13,1,0,0,3,-9,13,0,0,0,7,-100,-3,13,1,0,0,3,13,-6,13,1,0,0,5,-100,-4,13,1,0,0,1,7,13,-3,9,0,0,0,7,-100,-6,7,0,0,0,0,0,0,0,0,0,3,11,-100,-7,13,7,3,0,0,0,0,3,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt15[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,11,7,-100,-4,11,3,0,0,7,11,5,3,0,0,0,1,5,9,-100,-2,11,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,-100,13,5,0,0,0,0,0,0,0,1,7,11,13,-1,13,3,0,0,0,5,-100,1,0,0,0,0,0,0,0,3,-7,7,0,0,0,7,-100,1,0,0,0,0,0,0,0,11,-8,7,0,0,0,13,-100,-1,11,5,0,0,0,0,0,11,-9,1,0,0,3,-100,-3,7,0,0,0,0,11,-9,5,0,0,0,11,-100,-3,9,0,0,0,0,11,-9,9,0,0,0,5,-100,-3,11,0,0,0,0,11,-9,11,0,0,0,0,13,-100,-3,11,0,0,0,0,11,-9,13,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,13,-100,-4,0,0,0,0,11,-10,0,0,0,0,13,-100,-4,0,0,0,0,13,-10,0,0,0,0,-100,-4,0,0,0,9,-11,0,0,0,3,-100,-4,0,0,0,3,-11,0,0,0,9,-100,-4,0,0,0,0,13,-10,0,0,0,13,-100,-4,0,0,0,0,11,-9,5,0,0,0,-100,-4,0,0,0,0,11,-8,7,0,0,0,7,-100,-4,0,0,0,0,5,-7,9,0,0,0,3,-100,-4,0,0,0,0,0,3,11,13,-3,9,0,0,0,1,-100,-4,0,0,0,0,5,7,0,0,0,1,1,0,0,0,1,13,-100,-4,0,0,0,0,11,-2,9,5,1,0,0,3,7,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,7,-100,-4,0,0,0,0,3,-100,-3,7,0,0,0,0,0,9,-100,-1,5,0,0,0,0,0,0,0,0,0,0,5,-100,-1,3,1,0,0,0,0,0,0,0,0,0,5,-100,-101};
|
||||||
|
static int8_t lt16[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-19,7,11,-100,-6,11,5,1,0,0,1,5,11,-4,5,0,3,-100,-4,13,3,0,0,0,0,0,0,0,0,1,11,13,5,0,0,1,-100,-3,13,1,0,0,1,5,11,-3,11,3,0,0,0,0,0,3,-100,-2,13,1,0,0,3,-8,3,0,0,0,0,5,-100,-1,13,1,0,0,0,13,-8,7,0,0,0,0,5,-100,-1,3,0,0,0,5,-9,11,0,0,0,0,7,-100,9,0,0,0,0,11,-9,13,0,0,0,0,9,-100,3,0,0,0,0,-10,13,0,0,0,0,9,-100,1,0,0,0,1,-11,0,0,0,0,9,-100,0,0,0,0,3,-11,0,0,0,0,11,-100,0,0,0,0,5,-11,0,0,0,0,11,-100,0,0,0,0,9,-11,0,0,0,0,11,-100,0,0,0,0,11,-11,0,0,0,0,11,-100,0,0,0,0,11,-11,0,0,0,0,11,-100,1,0,0,0,11,-11,0,0,0,0,11,-100,3,0,0,0,9,-11,0,0,0,0,11,-100,7,0,0,0,5,-11,0,0,0,0,11,-100,11,0,0,0,0,-11,0,0,0,0,11,-100,-1,1,0,0,0,7,-9,11,0,0,0,0,11,-100,-1,9,0,0,0,0,13,-8,9,0,0,0,0,11,-100,-2,3,0,0,0,1,13,-7,5,0,0,0,0,11,-100,-2,13,3,0,0,0,1,9,13,-3,13,7,0,0,0,0,0,11,-100,-4,9,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,11,-100,-6,11,7,3,1,0,0,5,9,-1,13,0,0,0,0,11,-100,-16,0,0,0,0,13,-100,-16,0,0,0,0,13,-100,-16,0,0,0,0,13,-100,-16,0,0,0,0,13,-100,-15,13,0,0,0,0,13,-100,-15,9,0,0,0,0,11,-100,-15,1,0,0,0,0,5,-100,-12,7,5,1,0,0,0,0,0,0,1,3,9,-100,-11,13,1,0,0,0,0,0,0,0,0,0,0,7,-100,-101};
|
||||||
|
static int8_t lt17[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-3,13,5,0,3,-5,9,3,1,0,0,3,-100,-1,11,3,0,0,0,0,-3,7,0,0,0,0,0,0,0,5,-100,9,0,0,0,0,0,0,-2,3,0,0,0,0,0,0,0,0,1,-100,0,0,0,0,0,0,0,11,3,0,0,0,0,0,0,0,0,0,1,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-1,7,0,0,0,0,0,0,7,13,-2,11,7,3,1,3,11,-100,-2,3,0,0,0,0,3,-100,-2,7,0,0,0,0,9,-100,-2,11,0,0,0,0,13,-100,-2,13,0,0,0,0,-100,-3,0,0,0,0,-100,-3,0,0,0,0,13,-100,-3,0,0,0,0,13,-100,-3,0,0,0,0,13,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,9,-100,-1,13,3,0,0,0,0,1,13,-100,3,0,0,0,0,0,0,0,0,0,0,13,-100,5,1,0,0,0,0,0,0,0,0,3,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt18[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-3,13,7,1,0,1,3,9,11,9,9,13,-100,-2,13,1,0,0,0,0,0,0,0,0,0,5,-100,-2,1,0,5,13,-1,13,11,3,0,0,0,1,-100,-1,9,0,1,-6,9,0,0,0,13,-100,-1,3,0,9,-7,11,1,0,9,-100,-1,0,0,-9,13,1,5,-100,-1,0,0,11,-9,13,11,-100,13,0,0,1,13,-100,13,0,0,0,1,9,-100,-1,0,0,0,0,0,0,5,9,-100,-1,5,0,0,0,0,0,0,0,1,7,13,-100,-1,13,0,0,0,0,0,0,0,0,0,0,9,-100,-2,13,1,0,0,0,0,0,0,0,0,0,7,-100,-4,11,5,0,0,0,0,0,0,0,0,7,-100,-7,9,5,0,0,0,0,0,0,13,-100,-9,13,7,0,0,0,0,7,-100,-11,13,3,0,0,3,-100,-13,0,0,0,-100,7,5,-11,1,0,0,-100,1,0,5,-10,1,0,3,-100,0,0,0,3,-9,0,0,9,-100,1,0,0,0,3,13,-6,5,0,3,-100,7,0,0,0,0,1,7,11,13,13,9,3,0,1,13,-100,13,0,0,0,0,0,0,0,0,0,0,0,3,13,-100,-1,5,3,9,7,3,1,0,0,1,5,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt19[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,5,0,5,-100,-5,13,0,0,0,7,-100,-5,7,0,0,0,9,-100,-5,3,0,0,0,13,-100,-4,11,0,0,0,0,-100,-4,3,0,0,0,0,-100,-3,5,0,0,0,0,1,-100,-2,3,0,0,0,0,0,7,-100,13,1,0,0,0,0,0,0,1,11,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,5,13,-100,1,0,0,0,0,0,0,0,0,0,0,0,0,0,5,-100,-3,9,0,0,0,0,7,13,-100,-4,0,0,0,0,11,-100,-4,1,0,0,0,11,-100,-4,1,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,1,0,0,0,11,-100,-4,3,0,0,0,11,-100,-4,5,0,0,0,11,-100,-4,3,0,0,0,11,-100,-4,3,0,0,0,11,-100,-4,1,0,0,0,9,-100,-4,0,0,0,0,5,-100,-4,0,0,0,0,1,-100,-4,1,0,0,0,0,11,-100,-4,3,0,0,0,0,1,13,-1,9,5,1,3,-100,-4,9,0,0,0,0,0,0,0,0,0,0,5,-100,-5,5,0,0,0,0,0,0,0,0,5,-100,-6,9,3,1,0,0,1,5,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt20[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-4,13,9,1,0,13,-11,11,5,1,5,-100,-2,11,3,0,0,0,0,11,-8,11,5,0,0,0,0,1,-100,13,3,0,0,0,0,0,0,11,-6,7,1,0,0,0,0,0,0,7,-100,5,0,0,0,0,0,0,0,11,-5,5,0,0,0,0,0,0,0,0,11,-100,11,1,0,0,0,0,0,0,11,-5,9,0,0,0,0,0,0,0,0,11,-100,-2,11,1,0,0,0,0,11,-6,13,7,3,0,0,0,0,0,11,-100,-3,9,0,0,0,0,11,-9,9,0,0,0,0,11,-100,-3,11,0,0,0,0,11,-10,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,1,0,0,0,11,-9,13,0,0,0,0,11,-100,-4,1,0,0,0,11,-9,5,0,0,0,0,11,-100,-4,5,0,0,0,7,-8,7,0,0,0,0,0,11,-100,-4,7,0,0,0,0,13,-5,13,5,0,0,0,0,0,0,11,-100,-4,13,0,0,0,0,1,11,-1,13,11,5,0,0,7,5,0,0,0,0,3,13,-100,-5,3,0,0,0,0,0,0,0,0,0,3,13,-2,0,0,0,0,0,0,7,-100,-5,11,0,0,0,0,0,0,0,1,9,-4,0,0,0,0,0,0,0,-100,-6,13,5,1,0,1,3,9,-6,3,1,3,7,9,11,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt21[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,13,9,1,3,13,-5,13,1,0,0,0,0,1,3,9,-100,1,0,0,0,0,0,0,0,0,0,1,-5,1,0,0,0,0,0,0,0,0,9,-100,3,0,0,0,0,0,0,0,0,0,5,-5,3,0,0,0,0,0,0,0,0,13,-100,-1,9,3,0,0,0,0,0,5,13,-7,13,9,0,0,0,0,1,11,-100,-3,7,0,0,0,0,-11,7,0,0,5,-100,-4,0,0,0,0,9,-10,9,0,5,-100,-4,5,0,0,0,1,-10,5,0,11,-100,-4,11,0,0,0,0,9,-9,0,1,-100,-5,1,0,0,0,3,-8,9,0,7,-100,-5,7,0,0,0,0,13,-7,3,0,13,-100,-5,13,0,0,0,0,7,-6,13,0,3,-100,-6,3,0,0,0,1,-6,7,0,11,-100,-6,9,0,0,0,0,9,-5,0,1,-100,-6,13,0,0,0,0,3,-4,7,0,7,-100,-7,5,0,0,0,0,11,-3,1,0,13,-100,-7,11,0,0,0,0,1,-2,9,0,5,-100,-8,1,0,0,0,0,5,-1,1,0,11,-100,-8,7,0,0,0,0,0,0,0,3,-100,-8,13,0,0,0,0,0,0,0,9,-100,-9,3,0,0,0,0,0,1,-100,-9,9,0,0,0,0,0,7,-100,-10,0,0,0,0,0,13,-100,-10,5,0,0,0,1,-100,-10,13,1,0,0,7,-100,-11,11,1,5,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt22[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-29,13,-100,5,0,0,1,1,1,3,3,5,7,-3,7,0,0,0,0,0,0,0,0,0,11,-4,3,0,0,0,0,0,0,1,3,11,-100,5,0,0,0,0,0,0,0,1,7,-3,9,0,0,0,0,0,0,0,0,1,11,-4,9,1,0,0,0,0,0,0,1,13,-100,-1,13,5,0,0,0,0,0,13,-5,13,5,0,0,0,0,0,3,-8,9,0,0,0,0,5,-100,-3,5,0,0,0,0,-8,11,0,0,0,0,9,-9,9,0,0,9,-100,-4,1,0,0,0,13,-8,11,0,0,0,3,-10,0,3,-100,-4,7,0,0,0,11,-8,13,0,0,0,0,13,-8,9,0,11,-100,-4,13,0,0,0,7,-8,11,0,0,0,0,7,-8,1,1,-100,-5,5,0,0,1,-8,7,0,0,0,0,3,-8,5,11,-100,-5,11,0,0,0,9,-7,1,0,0,0,0,0,13,-100,-6,0,0,0,3,-6,9,0,3,13,0,0,0,7,-6,5,-100,-6,3,0,0,0,13,-5,1,0,11,-1,3,0,0,3,-6,1,-100,-6,9,0,0,0,9,-4,11,0,3,-2,7,0,0,0,13,-4,11,1,-100,-6,13,0,0,0,3,-4,5,0,9,-2,13,0,0,0,7,-4,5,3,-100,-7,3,0,0,0,13,-3,1,1,-4,0,0,0,1,-4,1,7,-100,-7,9,0,0,0,5,-2,13,0,7,-4,5,0,0,0,9,-2,9,0,13,-100,-8,1,0,0,0,13,-1,7,1,-5,11,0,0,0,1,-2,1,3,-100,-8,7,0,0,0,1,13,1,5,-6,1,0,0,0,13,9,0,9,-100,-8,13,0,0,0,0,0,0,11,-6,7,0,0,0,1,0,1,-100,-9,3,0,0,0,0,3,-7,13,0,0,0,0,0,9,-100,-9,9,0,0,0,0,5,-8,3,0,0,0,0,13,-100,-9,13,0,0,0,0,11,-8,9,0,0,0,1,-100,-10,3,0,0,0,-10,3,0,0,5,-100,-10,11,0,0,7,-10,13,1,1,13,-100,-11,11,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt23[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-16,13,13,-1,13,9,5,1,0,1,5,13,-100,-1,3,0,0,0,0,0,0,0,0,1,7,-4,1,0,0,0,0,0,0,0,0,0,1,-100,-1,1,0,0,0,0,0,0,0,0,1,11,-4,7,0,0,0,0,0,0,0,0,0,5,-100,-2,13,7,0,0,0,0,0,0,13,-6,13,5,0,0,0,0,5,9,13,-100,-4,13,3,0,0,0,0,3,-7,13,0,0,5,13,-100,-6,3,0,0,0,0,5,-6,7,0,7,-100,-7,3,0,0,0,0,11,-4,11,0,9,-100,-8,5,0,0,0,1,-3,11,0,7,-100,-9,3,0,0,0,1,11,11,0,7,-100,-9,13,1,0,0,0,0,0,7,-100,-10,13,1,0,0,0,0,9,-100,-11,11,0,0,0,0,1,-100,-12,0,0,0,0,0,7,-100,-11,9,0,0,0,0,0,0,11,-100,-10,9,0,5,13,3,0,0,0,1,13,-100,-9,11,0,3,-2,13,1,0,0,0,1,13,-100,-8,11,0,3,13,-3,13,1,0,0,0,1,13,-100,-7,9,0,1,13,-5,11,0,0,0,0,1,13,-100,-6,9,0,0,7,-7,9,0,0,0,0,1,11,-100,-5,5,0,0,0,13,-8,7,0,0,0,0,0,9,-100,-3,13,3,0,0,0,0,13,-8,13,0,0,0,0,0,0,5,-100,9,3,1,0,0,0,0,0,0,1,11,-6,11,1,0,0,0,0,0,0,0,1,3,13,-100,3,0,0,0,0,0,0,0,0,0,3,-6,11,5,3,1,0,0,0,1,1,3,5,-100,13,13,13,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
|
||||||
|
static int8_t lt24[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-1,13,13,-2,13,13,11,11,11,13,-6,11,11,11,11,11,11,11,11,13,-100,3,0,0,0,0,0,0,0,0,0,0,3,-4,1,0,0,0,0,0,0,0,0,1,-100,7,0,0,0,0,0,0,0,0,0,0,5,-4,3,0,0,0,0,0,0,0,0,9,-100,-2,11,5,0,0,0,0,0,0,11,-6,11,0,0,0,0,1,7,13,-100,-4,11,0,0,0,0,0,-8,9,0,0,1,13,-100,-5,7,0,0,0,0,13,-7,9,0,0,13,-100,-6,1,0,0,0,9,-7,5,0,5,-100,-6,7,0,0,0,3,-7,1,0,13,-100,-6,13,0,0,0,0,13,-5,11,0,1,-100,-7,5,0,0,0,7,-5,7,0,7,-100,-7,11,0,0,0,3,-5,1,0,11,-100,-8,1,0,0,0,13,-3,13,0,3,-100,-8,7,0,0,0,7,-3,7,0,9,-100,-8,13,0,0,0,3,-3,1,1,-100,-9,5,0,0,0,13,-1,9,0,7,-100,-9,11,0,0,0,3,13,1,0,13,-100,-10,1,0,0,0,0,0,3,-100,-10,9,0,0,0,0,0,9,-100,-11,1,0,0,0,1,-100,-11,5,0,0,0,7,-100,-11,9,0,0,0,13,-100,-11,13,0,0,3,-100,-12,0,0,9,-100,-12,0,1,-100,-11,13,0,7,-100,-11,7,0,11,-100,-11,1,0,-100,-2,7,0,1,7,-4,11,0,3,-100,-1,11,0,0,0,0,1,9,13,11,1,0,9,-100,-1,3,0,0,0,0,0,0,0,0,0,3,-100,-1,0,0,0,0,0,0,0,0,0,1,13,-100,-1,7,0,0,0,0,0,0,0,1,13,-100,-2,9,3,0,0,1,3,7,-100,-101};
|
||||||
|
static int8_t *lt[]={lt0,lt1,lt2,lt3,lt0,lt5,lt0,lt7,lt8,lt9,lt10,lt11,lt12,lt13,lt14,lt15,lt16,lt17,lt18,lt19,lt20,lt21,lt22,lt23,lt24,};
|
||||||
|
|
|
@ -0,0 +1,214 @@
|
||||||
|
// http://github.com/ITikhonov/captcha
|
||||||
|
const int gifsize;
|
||||||
|
void captcha(unsigned char im[70*200], unsigned char l[6]);
|
||||||
|
void makegif(unsigned char im[70*200], unsigned char gif[gifsize], int style);
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <ruby.h>
|
||||||
|
#include "font.h"
|
||||||
|
#include "colors.h"
|
||||||
|
|
||||||
|
static int8_t *lt[];
|
||||||
|
const int gifsize=17646;
|
||||||
|
|
||||||
|
void makegif(unsigned char im[70*200], unsigned char gif[gifsize], int style) {
|
||||||
|
// tag ; widthxheight ; GCT:0:0:7 ; bgcolor + aspect // GCT
|
||||||
|
// Image Separator // left x top // widthxheight // Flags
|
||||||
|
// LZW code size
|
||||||
|
srand(time(NULL));
|
||||||
|
int color_len = (int) sizeof(colors) / sizeof(colors[0]);
|
||||||
|
int color_idx = rand() % color_len;
|
||||||
|
if (style == 0) {
|
||||||
|
color_idx = 0;
|
||||||
|
}
|
||||||
|
memcpy(gif,colors[color_idx],13+48+10+1);
|
||||||
|
|
||||||
|
int x,y;
|
||||||
|
unsigned char *i=im;
|
||||||
|
unsigned char *p=gif+13+48+10+1;
|
||||||
|
for(y=0;y<70;y++) {
|
||||||
|
*p++=250; // Data length 5*50=250
|
||||||
|
for(x=0;x<50;x++)
|
||||||
|
{
|
||||||
|
unsigned char a=i[0]>>4,b=i[1]>>4,c=i[2]>>4,d=i[3]>>4;
|
||||||
|
|
||||||
|
p[0]=16|(a<<5); // bbb10000
|
||||||
|
p[1]=(a>>3)|64|(b<<7); // b10000xb
|
||||||
|
p[2]=b>>1; // 0000xbbb
|
||||||
|
p[3]=1|(c<<1); // 00xbbbb1
|
||||||
|
p[4]=4|(d<<3); // xbbbb100
|
||||||
|
i+=4;
|
||||||
|
p+=5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data length // End of LZW (b10001) // Terminator // GIF End
|
||||||
|
memcpy(gif+gifsize-4,"\x01" "\x11" "\x00" ";",4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int8_t sw[200]={0, 4, 8, 12, 16, 20, 23, 27, 31, 35, 39, 43, 47, 50, 54, 58, 61, 65, 68, 71, 75, 78, 81, 84, 87, 90, 93, 96, 98, 101, 103, 105, 108, 110, 112, 114, 115, 117, 119, 120, 121, 122, 123, 124, 125, 126, 126, 127, 127, 127, 127, 127, 127, 127, 126, 126, 125, 124, 123, 122, 121, 120, 119, 117, 115, 114, 112, 110, 108, 105, 103, 101, 98, 96, 93, 90, 87, 84, 81, 78, 75, 71, 68, 65, 61, 58, 54, 50, 47, 43, 39, 35, 31, 27, 23, 20, 16, 12, 8, 4, 0, -4, -8, -12, -16, -20, -23, -27, -31, -35, -39, -43, -47, -50, -54, -58, -61, -65, -68, -71, -75, -78, -81, -84, -87, -90, -93, -96, -98, -101, -103, -105, -108, -110, -112, -114, -115, -117, -119, -120, -121, -122, -123, -124, -125, -126, -126, -127, -127, -127, -127, -127, -127, -127, -126, -126, -125, -124, -123, -122, -121, -120, -119, -117, -115, -114, -112, -110, -108, -105, -103, -101, -98, -96, -93, -90, -87, -84, -81, -78, -75, -71, -68, -65, -61, -58, -54, -50, -47, -43, -39, -35, -31, -27, -23, -20, -16, -12, -8, -4};
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX(x,y) ((x>y)?(x):(y))
|
||||||
|
|
||||||
|
static int letter(int n, int pos, unsigned char im[70*200], unsigned char swr[200], uint8_t s1, uint8_t s2) {
|
||||||
|
int8_t *p=lt[n];
|
||||||
|
unsigned char *r=im+200*16+pos;
|
||||||
|
unsigned char *i=r;
|
||||||
|
int sk1=s1+pos;
|
||||||
|
int sk2=s2+pos;
|
||||||
|
int mpos=pos;
|
||||||
|
int row=0;
|
||||||
|
for(;*p!=-101;p++) {
|
||||||
|
if(*p<0) {
|
||||||
|
if(*p==-100) { r+=200; i=r; sk1=s1+pos; row++; continue; }
|
||||||
|
i+=-*p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sk1>=200) sk1=sk1%200;
|
||||||
|
int skew=sw[sk1]/16;
|
||||||
|
sk1+=(swr[pos+i-r]&0x1)+1;
|
||||||
|
|
||||||
|
if(sk2>=200) sk2=sk2%200;
|
||||||
|
int skewh=sw[sk2]/70;
|
||||||
|
sk2+=(swr[row]&0x1);
|
||||||
|
|
||||||
|
unsigned char *x=i+skew*200+skewh;
|
||||||
|
mpos=MAX(mpos,pos+i-r);
|
||||||
|
|
||||||
|
if((x-im)<70*200) *x=(*p)<<4;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return mpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NDOTS 100
|
||||||
|
|
||||||
|
uint32_t dr[NDOTS];
|
||||||
|
|
||||||
|
static void line(unsigned char im[70*200], unsigned char swr[200], uint8_t s1) {
|
||||||
|
int x;
|
||||||
|
int sk1=s1;
|
||||||
|
for(x=0;x<199;x++) {
|
||||||
|
if(sk1>=200) sk1=sk1%200;
|
||||||
|
int skew=sw[sk1]/16;
|
||||||
|
sk1+=swr[x]&0x3+1;
|
||||||
|
unsigned char *i= im+(200*(45+skew)+x);
|
||||||
|
i[0]=0; i[1]=0; i[200]=0; i[201]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dots(unsigned char im[70*200]) {
|
||||||
|
int n;
|
||||||
|
for(n=0;n<NDOTS;n++) {
|
||||||
|
uint32_t v=dr[n];
|
||||||
|
unsigned char *i=im+v%(200*67);
|
||||||
|
|
||||||
|
i[0]=0xff;
|
||||||
|
i[1]=0xff;
|
||||||
|
i[2]=0xff;
|
||||||
|
i[200]=0xff;
|
||||||
|
i[201]=0xff;
|
||||||
|
i[202]=0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void blur(unsigned char im[70*200]) {
|
||||||
|
unsigned char *i=im;
|
||||||
|
int x,y;
|
||||||
|
for(y=0;y<68;y++) {
|
||||||
|
for(x=0;x<198;x++) {
|
||||||
|
unsigned int c11=*i,c12=i[1],c21=i[200],c22=i[201];
|
||||||
|
*i++=((c11+c12+c21+c22)/4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void filter(unsigned char im[70*200]) {
|
||||||
|
unsigned char om[70*200];
|
||||||
|
unsigned char *i=im;
|
||||||
|
unsigned char *o=om;
|
||||||
|
|
||||||
|
memset(om,0xff,sizeof(om));
|
||||||
|
|
||||||
|
int x,y;
|
||||||
|
for(y=0;y<70;y++) {
|
||||||
|
for(x=4;x<200-4;x++) {
|
||||||
|
if(i[0]>0xf0 && i[1]<0xf0) { o[0]=0; o[1]=0; }
|
||||||
|
else if(i[0]<0xf0 && i[1]>0xf0) { o[0]=0; o[1]=0; }
|
||||||
|
|
||||||
|
i++;
|
||||||
|
o++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove(im,om,sizeof(om));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *letters="abcdafahijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
void captcha(unsigned char im[70*200], unsigned char l[6]) {
|
||||||
|
unsigned char swr[200];
|
||||||
|
uint8_t s1,s2;
|
||||||
|
|
||||||
|
int f=open("/dev/urandom",O_RDONLY);
|
||||||
|
read(f,l,5); read(f,swr,200); read(f,dr,sizeof(dr)); read(f,&s1,1); read(f,&s2,1);
|
||||||
|
close(f);
|
||||||
|
|
||||||
|
memset(im,0xff,200*70); s1=s1&0x7f; s2=s2&0x3f; l[0]%=25; l[1]%=25; l[2]%=25; l[3]%=25; l[4]%=25; l[5]=0;
|
||||||
|
int p=30; p=letter(l[0],p,im,swr,s1,s2); p=letter(l[1],p,im,swr,s1,s2); p=letter(l[2],p,im,swr,s1,s2); p=letter(l[3],p,im,swr,s1,s2); letter(l[4],p,im,swr,s1,s2);
|
||||||
|
line(im,swr,s1); dots(im); // blur(im); // filter(im);
|
||||||
|
l[0]=letters[l[0]]; l[1]=letters[l[1]]; l[2]=letters[l[2]]; l[3]=letters[l[3]]; l[4]=letters[l[4]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// #ifdef CAPTCHA
|
||||||
|
//
|
||||||
|
// int main() {
|
||||||
|
// char l[6];
|
||||||
|
// unsigned char im[70*200];
|
||||||
|
// unsigned char gif[gifsize];
|
||||||
|
//
|
||||||
|
// captcha(im,l);
|
||||||
|
// makegif(im,gif);
|
||||||
|
//
|
||||||
|
// write(1,gif,gifsize);
|
||||||
|
// write(2,l,5);
|
||||||
|
//
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
VALUE RuCaptcha = Qnil;
|
||||||
|
|
||||||
|
void Init_rucaptcha();
|
||||||
|
|
||||||
|
VALUE create(VALUE self, VALUE style);
|
||||||
|
|
||||||
|
void Init_rucaptcha() {
|
||||||
|
RuCaptcha = rb_define_module("RuCaptcha");
|
||||||
|
rb_define_singleton_method(RuCaptcha, "create", create, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE create(VALUE self, VALUE style) {
|
||||||
|
char l[6];
|
||||||
|
unsigned char im[80*200];
|
||||||
|
unsigned char gif[gifsize];
|
||||||
|
int i_style = FIX2INT(style);
|
||||||
|
|
||||||
|
captcha(im, l);
|
||||||
|
makegif(im, gif, i_style);
|
||||||
|
|
||||||
|
VALUE result = rb_ary_new2(2);
|
||||||
|
rb_ary_push(result, rb_str_new2(l));
|
||||||
|
rb_ary_push(result, rb_str_new(gif, gifsize));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
require 'rails'
|
require 'rails'
|
||||||
require 'action_controller'
|
require 'action_controller'
|
||||||
require 'active_support/all'
|
require 'active_support/all'
|
||||||
|
require_relative 'rucaptcha/rucaptcha'
|
||||||
require_relative 'rucaptcha/version'
|
require_relative 'rucaptcha/version'
|
||||||
require_relative 'rucaptcha/configuration'
|
require_relative 'rucaptcha/configuration'
|
||||||
require_relative 'rucaptcha/controller_helpers'
|
require_relative 'rucaptcha/controller_helpers'
|
||||||
require_relative 'rucaptcha/view_helpers'
|
require_relative 'rucaptcha/view_helpers'
|
||||||
require_relative 'rucaptcha/cache'
|
require_relative 'rucaptcha/cache'
|
||||||
require_relative 'rucaptcha/captcha'
|
|
||||||
require_relative 'rucaptcha/engine'
|
require_relative 'rucaptcha/engine'
|
||||||
|
|
||||||
module RuCaptcha
|
module RuCaptcha
|
||||||
|
@ -14,12 +14,8 @@ module RuCaptcha
|
||||||
def config
|
def config
|
||||||
return @config if defined?(@config)
|
return @config if defined?(@config)
|
||||||
@config = Configuration.new
|
@config = Configuration.new
|
||||||
@config.len = 4
|
|
||||||
@config.font_size = 45
|
|
||||||
@config.implode = 0.3
|
|
||||||
@config.cache_limit = 100
|
|
||||||
@config.expires_in = 2.minutes
|
|
||||||
@config.style = :colorful
|
@config.style = :colorful
|
||||||
|
@config.expires_in = 2.minutes
|
||||||
if Rails.application
|
if Rails.application
|
||||||
@config.cache_store = Rails.application.config.cache_store
|
@config.cache_store = Rails.application.config.cache_store
|
||||||
else
|
else
|
||||||
|
@ -31,6 +27,11 @@ module RuCaptcha
|
||||||
def configure(&block)
|
def configure(&block)
|
||||||
config.instance_exec(&block)
|
config.instance_exec(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate()
|
||||||
|
style = config.style == :colorful ? 1 : 0
|
||||||
|
self.create(style)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,46 +8,4 @@ module RuCaptcha
|
||||||
@cache
|
@cache
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# File Cache
|
|
||||||
module Cache
|
|
||||||
def self.prepended(base)
|
|
||||||
class << base
|
|
||||||
prepend ClassMethods
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module ClassMethods
|
|
||||||
def create(code)
|
|
||||||
file_cache.fetch(code, expires_in: 1.days) do
|
|
||||||
super(code)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def random_chars
|
|
||||||
if cached_codes.length >= RuCaptcha.config.cache_limit
|
|
||||||
return cached_codes.sample
|
|
||||||
end
|
|
||||||
|
|
||||||
code = super
|
|
||||||
cached_codes << code
|
|
||||||
code
|
|
||||||
end
|
|
||||||
|
|
||||||
def file_cache
|
|
||||||
return @file_cache if defined?(@file_cache)
|
|
||||||
|
|
||||||
cache_path = Rails.root.join('tmp', 'cache', 'rucaptcha')
|
|
||||||
FileUtils.mkdir_p(cache_path) unless File.exist? cache_path
|
|
||||||
@file_cache = ActiveSupport::Cache::FileStore.new(cache_path)
|
|
||||||
# clear expired captcha cache files on Process restart
|
|
||||||
@file_cache.cleanup
|
|
||||||
@file_cache
|
|
||||||
end
|
|
||||||
|
|
||||||
def cached_codes
|
|
||||||
@cached_codes ||= []
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
require 'open3'
|
|
||||||
|
|
||||||
module RuCaptcha
|
|
||||||
class Captcha
|
|
||||||
class << self
|
|
||||||
# Genrate ranom RGB color
|
|
||||||
def random_color
|
|
||||||
if RuCaptcha.config.style == :colorful
|
|
||||||
color1 = rand(56) + 15
|
|
||||||
color2 = rand(10) + 140
|
|
||||||
color = [color1, color2, rand(15)]
|
|
||||||
color.shuffle!
|
|
||||||
color
|
|
||||||
else
|
|
||||||
color_seed = rand(40) + 10
|
|
||||||
[color_seed, color_seed, color_seed]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Genrate random Captcha code
|
|
||||||
def random_chars
|
|
||||||
chars = SecureRandom.hex(RuCaptcha.config.len / 2).downcase
|
|
||||||
chars.gsub!(/[0ol1]/i, (rand(8) + 2).to_s)
|
|
||||||
chars
|
|
||||||
end
|
|
||||||
|
|
||||||
# Create Captcha image by code
|
|
||||||
def create(code)
|
|
||||||
chars = code.split('')
|
|
||||||
full_width = RuCaptcha.config.font_size * chars.size
|
|
||||||
full_height = RuCaptcha.config.font_size
|
|
||||||
size = "#{full_width}x#{full_height}"
|
|
||||||
|
|
||||||
return convert_for_windows(size, code) if Gem.win_platform?
|
|
||||||
|
|
||||||
opts = command_line_opts(chars, full_width)
|
|
||||||
convert(size, opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def command_line_opts(chars, full_width)
|
|
||||||
font_size = RuCaptcha.config.font_size
|
|
||||||
all_left = 20
|
|
||||||
half_width = full_width / 2
|
|
||||||
text_top = 0
|
|
||||||
text_left = 0 - (font_size * 0.28).to_i
|
|
||||||
text_width = font_size + text_left
|
|
||||||
|
|
||||||
opts = { text: [], line: [] }
|
|
||||||
rgbs = uniq_rgbs_for_each_chars(chars)
|
|
||||||
|
|
||||||
chars.each_with_index do |char, i|
|
|
||||||
rgb = RuCaptcha.config.style == :colorful ? rgbs[i] : rgbs[0]
|
|
||||||
text_color = "rgba(#{rgb.join(',')}, 1)"
|
|
||||||
line_color = "rgba(#{rgb.join(',')}, 0.6)"
|
|
||||||
opts[:text] << %(-fill '#{text_color}' -draw 'text #{(text_left + text_width) * i + all_left},#{text_top} "#{char}"')
|
|
||||||
|
|
||||||
left_y = rand_line_top(text_top, font_size)
|
|
||||||
right_x = half_width + (half_width * 0.3).to_i
|
|
||||||
right_y = rand_line_top(text_top, font_size)
|
|
||||||
opts[:line] << %(-draw 'stroke #{line_color} line #{rand(10)},#{left_y} #{right_x},#{right_y}')
|
|
||||||
end
|
|
||||||
opts
|
|
||||||
end
|
|
||||||
|
|
||||||
def convert(size, opts)
|
|
||||||
stroke_width = (RuCaptcha.config.font_size * 0.05).to_i + 1
|
|
||||||
command = <<-CODE
|
|
||||||
convert -size #{size} \
|
|
||||||
-strokewidth #{stroke_width} \
|
|
||||||
#{opts[:line].join(' ')} \
|
|
||||||
-pointsize #{RuCaptcha.config.font_size} -weight 500 \
|
|
||||||
#{opts[:text].join(' ')} \
|
|
||||||
-wave #{rand(2) + 3}x#{rand(2) + 1} \
|
|
||||||
-rotate #{rand(10) - 5} \
|
|
||||||
-gravity NorthWest -sketch 1x10+#{rand(2)} \
|
|
||||||
-fill none \
|
|
||||||
-implode #{RuCaptcha.config.implode} -trim label:- png:-
|
|
||||||
CODE
|
|
||||||
command.strip!
|
|
||||||
out, err, _st = Open3.capture3(command)
|
|
||||||
warn " RuCaptcha #{err.strip}" if err.present?
|
|
||||||
out
|
|
||||||
end
|
|
||||||
|
|
||||||
# Generate a simple captcha image for Windows Platform
|
|
||||||
def convert_for_windows(size, code)
|
|
||||||
png_file_path = Rails.root.join('tmp', 'cache', "#{code}.png")
|
|
||||||
command = "convert -size #{size} xc:White -gravity Center -weight 12 -pointsize 20 -annotate 0 \"#{code}\" -trim #{png_file_path}"
|
|
||||||
_out, err, _st = Open3.capture3(command)
|
|
||||||
warn " RuCaptcha #{err.strip}" if err.present?
|
|
||||||
png_file_path
|
|
||||||
end
|
|
||||||
|
|
||||||
# Geneate a uniq rgba colors for each chars
|
|
||||||
def uniq_rgbs_for_each_chars(chars)
|
|
||||||
rgbs = []
|
|
||||||
chars.count.times do |i|
|
|
||||||
color = random_color
|
|
||||||
if i > 0
|
|
||||||
preview_color = rgbs[i - 1]
|
|
||||||
# Avoid color same as preview color
|
|
||||||
if color.index(color.min) == preview_color.index(preview_color.min) &&
|
|
||||||
color.index(color.max) == preview_color.index(preview_color.max)
|
|
||||||
# adjust RGB order
|
|
||||||
color = [color[1], color[2], color[0]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rgbs << color
|
|
||||||
end
|
|
||||||
rgbs
|
|
||||||
end
|
|
||||||
|
|
||||||
def rand_line_top(text_top, font_size)
|
|
||||||
text_top + rand(font_size * 0.7).to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
def warn(msg)
|
|
||||||
msg = " RuCaptcha #{msg}"
|
|
||||||
Rails.logger.error(msg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,20 +1,11 @@
|
||||||
module RuCaptcha
|
module RuCaptcha
|
||||||
class Configuration
|
class Configuration
|
||||||
# Image font size, default 45
|
|
||||||
attr_accessor :font_size
|
|
||||||
# Number of chars, default 4
|
|
||||||
attr_accessor :len
|
|
||||||
# implode, default 0.3
|
|
||||||
attr_accessor :implode
|
|
||||||
# Store Captcha code where, this config more like Rails config.cache_store
|
# Store Captcha code where, this config more like Rails config.cache_store
|
||||||
# default: Rails application config.cache_store
|
# default: Rails application config.cache_store
|
||||||
attr_accessor :cache_store
|
attr_accessor :cache_store
|
||||||
# Number of Captcha codes limit
|
|
||||||
# set 0 to disable limit and file cache, default: 100
|
|
||||||
attr_accessor :cache_limit
|
|
||||||
# Color style, default: :colorful, allows: [:colorful, :black_white]
|
|
||||||
attr_accessor :style
|
|
||||||
# rucaptcha expire time, default 2 minutes
|
# rucaptcha expire time, default 2 minutes
|
||||||
attr_accessor :expires_in
|
attr_accessor :expires_in
|
||||||
|
# Color style, default: :colorful, allows: [:colorful, :black_white]
|
||||||
|
attr_accessor :style
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,13 +14,13 @@ module RuCaptcha
|
||||||
|
|
||||||
# Generate a new Captcha
|
# Generate a new Captcha
|
||||||
def generate_rucaptcha
|
def generate_rucaptcha
|
||||||
code = RuCaptcha::Captcha.random_chars
|
res = RuCaptcha.generate()
|
||||||
session_val = {
|
session_val = {
|
||||||
code: code,
|
code: res[0],
|
||||||
time: Time.now.to_i
|
time: Time.now.to_i
|
||||||
}
|
}
|
||||||
RuCaptcha.cache.write(rucaptcha_sesion_key_key, session_val, expires_in: RuCaptcha.config.expires_in)
|
RuCaptcha.cache.write(rucaptcha_sesion_key_key, session_val, expires_in: RuCaptcha.config.expires_in)
|
||||||
RuCaptcha::Captcha.create(code)
|
res[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Verify captcha code
|
# Verify captcha code
|
||||||
|
|
|
@ -3,11 +3,6 @@ module RuCaptcha
|
||||||
isolate_namespace RuCaptcha
|
isolate_namespace RuCaptcha
|
||||||
|
|
||||||
initializer 'rucaptcha.prepend.cache' do
|
initializer 'rucaptcha.prepend.cache' do
|
||||||
# enable cache if cache_limit less than 1
|
|
||||||
if RuCaptcha.config.cache_limit >= 1
|
|
||||||
RuCaptcha::Captcha.send(:prepend, RuCaptcha::Cache)
|
|
||||||
end
|
|
||||||
|
|
||||||
cache_store = RuCaptcha.config.cache_store
|
cache_store = RuCaptcha.config.cache_store
|
||||||
store_name = cache_store.is_a?(Array) ? cache_store.first : cache_store
|
store_name = cache_store.is_a?(Array) ? cache_store.first : cache_store
|
||||||
if [:memory_store, :null_store, :file_store].include?(store_name)
|
if [:memory_store, :null_store, :file_store].include?(store_name)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module RuCaptcha
|
module RuCaptcha
|
||||||
VERSION = '1.2.0'
|
VERSION = '2.0.0'
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,8 @@ module RuCaptcha
|
||||||
opts[:type] = 'text'
|
opts[:type] = 'text'
|
||||||
opts[:autocorrect] = 'off'
|
opts[:autocorrect] = 'off'
|
||||||
opts[:autocapitalize] = 'off'
|
opts[:autocapitalize] = 'off'
|
||||||
opts[:pattern] = '[0-9a-zA-Z]*'
|
opts[:pattern] = '[a-zA-Z]*'
|
||||||
opts[:maxlength] = RuCaptcha.config.len
|
opts[:maxlength] = 5
|
||||||
opts[:autocomplete] = 'off'
|
opts[:autocomplete] = 'off'
|
||||||
tag(:input, opts)
|
tag(:input, opts)
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,12 +8,18 @@ Gem::Specification.new do |s|
|
||||||
s.version = RuCaptcha::VERSION
|
s.version = RuCaptcha::VERSION
|
||||||
s.authors = 'Jason Lee'
|
s.authors = 'Jason Lee'
|
||||||
s.email = 'huacnlee@gmail.com'
|
s.email = 'huacnlee@gmail.com'
|
||||||
s.files = Dir.glob('lib/**/*') + Dir.glob('app/**/*') + Dir.glob('config/**/*') + %w(README.md CHANGELOG.md)
|
s.files = Dir.glob('lib/**/*.{rb}') +
|
||||||
|
Dir.glob("ext/**/*.{h,c,rb}") +
|
||||||
|
Dir.glob('app/**/*') +
|
||||||
|
Dir.glob('config/**/*') +
|
||||||
|
%w[README.md CHANGELOG.md]
|
||||||
s.homepage = 'https://github.com/huacnlee/rucaptcha'
|
s.homepage = 'https://github.com/huacnlee/rucaptcha'
|
||||||
s.require_paths = ['lib']
|
s.require_paths = ['lib']
|
||||||
|
s.extensions = %w[ext/rucaptcha/extconf.rb]
|
||||||
s.summary = 'This is a Captcha gem for Rails Application. It run ImageMagick command to draw Captcha image.'
|
s.summary = 'This is a Captcha gem for Rails Application. It run ImageMagick command to draw Captcha image.'
|
||||||
s.license = "MIT"
|
s.license = "MIT"
|
||||||
s.required_ruby_version = ">= 2.0.0"
|
s.required_ruby_version = ">= 2.0.0"
|
||||||
|
|
||||||
s.add_dependency 'railties', '>= 3.2'
|
s.add_dependency 'railties', '>= 3.2'
|
||||||
|
s.add_development_dependency 'rake-compiler', '~> 1'
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe RuCaptcha::Cache do
|
|
||||||
before(:all) do
|
|
||||||
RuCaptcha::Captcha.send(:prepend, RuCaptcha::Cache)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.random_chars_with_cache' do
|
|
||||||
it 'should generate max chars by config.cache_limit' do
|
|
||||||
allow(RuCaptcha.config).to receive(:cache_limit).and_return(5)
|
|
||||||
items = []
|
|
||||||
100.times do
|
|
||||||
items << RuCaptcha::Captcha.random_chars
|
|
||||||
end
|
|
||||||
expect(items.uniq.length).to eq RuCaptcha.config.cache_limit
|
|
||||||
expect(RuCaptcha::Captcha.cached_codes).to eq items.uniq
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.create' do
|
|
||||||
it 'should work' do
|
|
||||||
expect(RuCaptcha::Captcha).to receive(:create).and_return('aabb')
|
|
||||||
expect(RuCaptcha::Captcha.create('abcd')).to eq('aabb')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,64 +1,28 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe RuCaptcha::Captcha do
|
describe RuCaptcha do
|
||||||
describe '.random_chars' do
|
describe '.generate' do
|
||||||
|
it 'should work' do
|
||||||
|
res = RuCaptcha.generate()
|
||||||
|
expect(res.length).to eq(2)
|
||||||
|
expect(res[0].length).to eq(5)
|
||||||
|
expect(res[1]).not_to eq(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.create' do
|
||||||
it 'should len equal config.len' do
|
it 'should len equal config.len' do
|
||||||
expect(RuCaptcha::Captcha.random_chars.length).to eq(RuCaptcha.config.len)
|
res = RuCaptcha.create(0)
|
||||||
|
expect(res.length).to eq(2)
|
||||||
|
expect(res[0].length).to eq(5)
|
||||||
|
expect(res[1]).not_to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should return 0-9 and lower str' do
|
it 'should work with color style' do
|
||||||
expect(RuCaptcha::Captcha.random_chars).to match(/[a-z0-9]/)
|
res = RuCaptcha.create(1)
|
||||||
end
|
expect(res.length).to eq(2)
|
||||||
|
expect(res[0].length).to eq(5)
|
||||||
it 'should not include [0ol1]' do
|
expect(res[1]).not_to eq(nil)
|
||||||
10_000.times do
|
|
||||||
expect(RuCaptcha::Captcha.random_chars).not_to match(/[0ol1]/i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.random_color' do
|
|
||||||
it 'should return colorful array' do
|
|
||||||
allow(RuCaptcha.config).to receive(:style).and_return(:colorful)
|
|
||||||
colors = RuCaptcha::Captcha.random_color
|
|
||||||
expect(colors.uniq.size >= 2).to eq true
|
|
||||||
colors1 = RuCaptcha::Captcha.random_color
|
|
||||||
expect(colors).not_to eq colors1
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should return black color array' do
|
|
||||||
allow(RuCaptcha.config).to receive(:style).and_return(:black_white)
|
|
||||||
colors = RuCaptcha::Captcha.random_color
|
|
||||||
expect(colors.uniq.size).to eq 1
|
|
||||||
colors1 = RuCaptcha::Captcha.random_color
|
|
||||||
expect(colors).not_to eq colors1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.rand_line_top' do
|
|
||||||
it 'should work' do
|
|
||||||
expect(RuCaptcha::Captcha.send(:rand_line_top, 1, 24)).to be_a(Integer)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.uniq_rgbs_for_each_chars' do
|
|
||||||
let(:chars) { %w(a b c d e) }
|
|
||||||
let(:colors) { RuCaptcha::Captcha.send(:uniq_rgbs_for_each_chars, chars) }
|
|
||||||
|
|
||||||
it 'should work' do
|
|
||||||
expect(colors.length).to eq chars.length
|
|
||||||
expect(colors[0].length).to eq 3
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'Be sure the color not same as preview color' do
|
|
||||||
pre_rgb = nil
|
|
||||||
colors.each do |rgb|
|
|
||||||
if pre_rgb
|
|
||||||
same = rgb.index(rgb.min) == pre_rgb.index(rgb.min) && rgb.index(rgb.max) == pre_rgb.index(pre_rgb.max)
|
|
||||||
expect(same).not_to eq true
|
|
||||||
end
|
|
||||||
pre_rgb = rgb
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,9 +3,6 @@ require 'spec_helper'
|
||||||
describe RuCaptcha do
|
describe RuCaptcha do
|
||||||
describe 'normal' do
|
describe 'normal' do
|
||||||
it 'should read right config with spec_helper set' do
|
it 'should read right config with spec_helper set' do
|
||||||
expect(RuCaptcha.config.len).to eq(2)
|
|
||||||
expect(RuCaptcha.config.font_size).to eq(48)
|
|
||||||
expect(RuCaptcha.config.implode).to eq(0.111)
|
|
||||||
expect(RuCaptcha.config.expires_in).to eq(2.minutes)
|
expect(RuCaptcha.config.expires_in).to eq(2.minutes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,9 +37,9 @@ describe RuCaptcha do
|
||||||
|
|
||||||
describe '.generate_rucaptcha' do
|
describe '.generate_rucaptcha' do
|
||||||
it 'should work' do
|
it 'should work' do
|
||||||
expect(RuCaptcha::Captcha).to receive(:random_chars).and_return('abcd')
|
allow(RuCaptcha).to receive(:create).and_return(['abcde', 'fake image data'])
|
||||||
expect(simple.generate_rucaptcha).not_to be_nil
|
expect(simple.generate_rucaptcha).to eq 'fake image data'
|
||||||
expect(simple.custom_session[:code]).to eq('abcd')
|
expect(simple.custom_session[:code]).to eq('abcde')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,5 @@ module Rails
|
||||||
end
|
end
|
||||||
|
|
||||||
RuCaptcha.configure do
|
RuCaptcha.configure do
|
||||||
self.len = 2
|
|
||||||
self.font_size = 48
|
|
||||||
self.implode = 0.111
|
|
||||||
self.cache_store = :mem_cache_store
|
self.cache_store = :mem_cache_store
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue