Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix rand.Intn painc #118

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions captcha_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestCaptcha_GenerateB64s(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := NewCaptcha(tt.fields.Driver, tt.fields.Store)
gotId, b64s,_, err := c.Generate()
gotId, b64s, _, err := c.Generate()
if (err != nil) != tt.wantErr {
t.Errorf("Captcha.Generate() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down Expand Up @@ -122,7 +122,7 @@ func TestCaptcha_Generate(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotId, gotB64s,_, err := tt.c.Generate()
gotId, gotB64s, _, err := tt.c.Generate()
if (err != nil) != tt.wantErr {
t.Errorf("Captcha.Generate() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
13 changes: 6 additions & 7 deletions driver_chinese.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package base64Captcha

import (
"image/color"
"math/rand"
"strings"

"github.com/golang/freetype/truetype"
)

//DriverChinese is a driver of unicode Chinese characters.
// DriverChinese is a driver of unicode Chinese characters.
type DriverChinese struct {
//Height png height in pixel.
Height int
Expand Down Expand Up @@ -38,7 +37,7 @@ type DriverChinese struct {
fontsArray []*truetype.Font
}

//NewDriverChinese creates a driver of Chinese characters
// NewDriverChinese creates a driver of Chinese characters
func NewDriverChinese(height int, width int, noiseCount int, showLineOptions int, length int, source string, bgColor *color.RGBA, fontsStorage FontsStorage, fonts []string) *DriverChinese {
if fontsStorage == nil {
fontsStorage = DefaultEmbeddedFonts
Expand All @@ -57,7 +56,7 @@ func NewDriverChinese(height int, width int, noiseCount int, showLineOptions int
return &DriverChinese{Height: height, Width: width, NoiseCount: noiseCount, ShowLineOptions: showLineOptions, Length: length, Source: source, BgColor: bgColor, fontsStorage: fontsStorage, fontsArray: tfs}
}

//ConvertFonts loads fonts by names
// ConvertFonts loads fonts by names
func (d *DriverChinese) ConvertFonts() *DriverChinese {
if d.fontsStorage == nil {
d.fontsStorage = DefaultEmbeddedFonts
Expand All @@ -76,7 +75,7 @@ func (d *DriverChinese) ConvertFonts() *DriverChinese {
return d
}

//GenerateIdQuestionAnswer generates captcha content and its answer
// GenerateIdQuestionAnswer generates captcha content and its answer
func (d *DriverChinese) GenerateIdQuestionAnswer() (id, content, answer string) {
id = RandomId()

Expand All @@ -93,14 +92,14 @@ func (d *DriverChinese) GenerateIdQuestionAnswer() (id, content, answer string)

res := make([]string, d.Length)
for k := range res {
res[k] = ss[rand.Intn(length)]
res[k] = ss[randIntn(length)]
}

content = strings.Join(res, "")
return id, content, content
}

//DrawCaptcha generates captcha item(image)
// DrawCaptcha generates captcha item(image)
func (d *DriverChinese) DrawCaptcha(content string) (item Item, err error) {

var bgc color.RGBA
Expand Down
4 changes: 2 additions & 2 deletions driver_digit.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ func (d *DriverDigit) DrawCaptcha(content string) (item Item, err error) {
} else {
border = d.Width / 5
}
x := rand.Intn(maxx-border*2) + border
y := rand.Intn(maxy-border*2) + border
x := randIntn(maxx-border*2) + border
y := randIntn(maxy-border*2) + border
// Draw digits.
for _, n := range digits {
itemDigit.drawDigit(digitFontData[n], x, y)
Expand Down
13 changes: 6 additions & 7 deletions driver_language.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ package base64Captcha
import (
"image/color"
"log"
"math/rand"

"github.com/golang/freetype/truetype"
)

//https://en.wikipedia.org/wiki/Unicode_block
// https://en.wikipedia.org/wiki/Unicode_block
var langMap = map[string][]int{
//"zh-CN": []int{19968, 40869},
"latin": {0x0000, 0x007f},
Expand All @@ -33,13 +32,13 @@ func generateRandomRune(size int, code string) string {
end := lang[1]
randRune := make([]rune, size)
for i := range randRune {
idx := rand.Intn(end-start) + start
idx := randIntn(end-start) + start
randRune[i] = rune(idx)
}
return string(randRune)
}

//DriverLanguage generates language unicode by lanuage
// DriverLanguage generates language unicode by lanuage
type DriverLanguage struct {
// Height png height in pixel.
Height int
Expand All @@ -66,19 +65,19 @@ type DriverLanguage struct {
LanguageCode string
}

//NewDriverLanguage creates a driver
// NewDriverLanguage creates a driver
func NewDriverLanguage(height int, width int, noiseCount int, showLineOptions int, length int, bgColor *color.RGBA, fontsStorage FontsStorage, fonts []*truetype.Font, languageCode string) *DriverLanguage {
return &DriverLanguage{Height: height, Width: width, NoiseCount: noiseCount, ShowLineOptions: showLineOptions, Length: length, BgColor: bgColor, fontsStorage: fontsStorage, Fonts: fonts, LanguageCode: languageCode}
}

//GenerateIdQuestionAnswer creates content and answer
// GenerateIdQuestionAnswer creates content and answer
func (d *DriverLanguage) GenerateIdQuestionAnswer() (id, content, answer string) {
id = RandomId()
content = generateRandomRune(d.Length, d.LanguageCode)
return id, content, content
}

//DrawCaptcha creates item
// DrawCaptcha creates item
func (d *DriverLanguage) DrawCaptcha(content string) (item Item, err error) {
var bgc color.RGBA
if d.BgColor != nil {
Expand Down
8 changes: 3 additions & 5 deletions fonts.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package base64Captcha

import (
"math/rand"

"github.com/golang/freetype/truetype"
)

Expand All @@ -18,11 +16,11 @@ var fontsSimple = DefaultEmbeddedFonts.LoadFontsByNames([]string{
"fonts/chromohv.ttf",
})

//var fontemoji = loadFontByName("fonts/seguiemj.ttf")
// var fontemoji = loadFontByName("fonts/seguiemj.ttf")
var fontsAll = append(fontsSimple, fontChinese)
var fontChinese = DefaultEmbeddedFonts.LoadFontByName("fonts/wqy-microhei.ttc")

//randFontFrom choose random font family.选择随机的字体
// randFontFrom choose random font family.选择随机的字体
func randFontFrom(fonts []*truetype.Font) *truetype.Font {
fontCount := len(fonts)

Expand All @@ -31,7 +29,7 @@ func randFontFrom(fonts []*truetype.Font) *truetype.Font {
fonts = fontsAll
fontCount = len(fontsAll)
}
index := rand.Intn(fontCount)
index := randIntn(fontCount)
return fonts[index]
}

Expand Down
4 changes: 2 additions & 2 deletions item_audio.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"math/rand"
)

//ItemAudio captcha-audio-engine return type.
// ItemAudio captcha-audio-engine return type.
type ItemAudio struct {
answer string
body *bytes.Buffer
Expand Down Expand Up @@ -81,7 +81,7 @@ func (a *ItemAudio) makeBackgroundSound(length int) []byte {
for i := 0; i < length/(sampleRate/10); i++ {
snd := reversedSound(a.digitSounds[rand.Intn(10)])
//snd = changeSpeed(snd, a.rng.Float(0.8, 1.2))
place := rand.Intn(len(b) - len(snd))
place := randIntn(len(b) - len(snd))
setSoundLevel(snd, randFloat64Range(0.04, 0.08))
mixSound(b[place:], snd)
}
Expand Down
45 changes: 23 additions & 22 deletions item_char.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import (
"encoding/base64"
"errors"
"fmt"
"github.com/golang/freetype"
"github.com/golang/freetype/truetype"
"golang.org/x/image/font"
"image"
"image/color"
"image/draw"
Expand All @@ -16,17 +13,21 @@ import (
"log"
"math"
"math/rand"

"github.com/golang/freetype"
"github.com/golang/freetype/truetype"
"golang.org/x/image/font"
)

//ItemChar captcha item of unicode characters
// ItemChar captcha item of unicode characters
type ItemChar struct {
bgColor color.Color
width int
height int
nrgba *image.NRGBA
}

//NewItemChar creates a captcha item of characters
// NewItemChar creates a captcha item of characters
func NewItemChar(w int, h int, bgColor color.RGBA) *ItemChar {
d := ItemChar{width: w, height: h}
m := image.NewNRGBA(image.Rect(0, 0, w, h))
Expand All @@ -35,18 +36,18 @@ func NewItemChar(w int, h int, bgColor color.RGBA) *ItemChar {
return &d
}

//drawHollowLine draw strong and bold white line.
// drawHollowLine draw strong and bold white line.
func (item *ItemChar) drawHollowLine() *ItemChar {

first := item.width / 20
end := first * 19

lineColor := RandLightColor()

x1 := float64(rand.Intn(first))
//y1 := float64(rand.Intn(y)+y);
x1 := float64(randIntn(first))
//y1 := float64(randIntn(y)+y);

x2 := float64(rand.Intn(first) + end)
x2 := float64(randIntn(first) + end)

multiple := float64(rand.Intn(5)+3) / float64(5)
if int(multiple*10)%3 == 0 {
Expand All @@ -72,12 +73,12 @@ func (item *ItemChar) drawHollowLine() *ItemChar {
return item
}

//drawSineLine draw a sine line.
// drawSineLine draw a sine line.
func (item *ItemChar) drawSineLine() *ItemChar {
var py float64

//振幅
a := rand.Intn(item.height / 2)
a := randIntn(item.height / 2)

//Y轴方向偏移量
b := random(int64(-item.height/4), int64(item.height/4))
Expand Down Expand Up @@ -116,7 +117,7 @@ func (item *ItemChar) drawSineLine() *ItemChar {
return item
}

//drawSlimLine draw n slim-random-color lines.
// drawSlimLine draw n slim-random-color lines.
func (item *ItemChar) drawSlimLine(num int) *ItemChar {

first := item.width / 10
Expand All @@ -126,15 +127,15 @@ func (item *ItemChar) drawSlimLine(num int) *ItemChar {

for i := 0; i < num; i++ {

point1 := point{X: rand.Intn(first), Y: rand.Intn(y)}
point2 := point{X: rand.Intn(first) + end, Y: rand.Intn(y)}
point1 := point{X: randIntn(first), Y: randIntn(y)}
point2 := point{X: randIntn(first) + end, Y: randIntn(y)}

if i%2 == 0 {
point1.Y = rand.Intn(y) + y*2
point2.Y = rand.Intn(y)
point1.Y = randIntn(y) + y*2
point2.Y = randIntn(y)
} else {
point1.Y = rand.Intn(y) + y*(i%2)
point2.Y = rand.Intn(y) + y*2
point1.Y = randIntn(y) + y*(i%2)
point2.Y = randIntn(y) + y*2
}

item.drawBeeline(point1, point2, RandDeepColor())
Expand Down Expand Up @@ -187,8 +188,8 @@ func (item *ItemChar) drawNoise(noiseText string, fonts []*truetype.Font) error
rawFontSize := float64(item.height) / (1 + float64(rand.Intn(7))/float64(10))

for _, char := range noiseText {
rw := rand.Intn(item.width)
rh := rand.Intn(item.height)
rw := randIntn(item.width)
rh := randIntn(item.height)
fontSize := rawFontSize/2 + float64(rand.Intn(5))
c.SetSrc(image.NewUniform(RandLightColor()))
c.SetFontSize(fontSize)
Expand Down Expand Up @@ -222,7 +223,7 @@ func (item *ItemChar) drawText(text string, fonts []*truetype.Font) error {
c.SetFontSize(float64(fontSize))
c.SetFont(randFontFrom(fonts))
x := fontWidth*i + fontWidth/fontSize
y := item.height/2 + fontSize/2 - rand.Intn(item.height/16*3)
y := item.height/2 + fontSize/2 - randIntn(item.height/16*3)
pt := freetype.Pt(x, y)
if _, err := c.DrawString(string(s), pt); err != nil {
return err
Expand All @@ -231,7 +232,7 @@ func (item *ItemChar) drawText(text string, fonts []*truetype.Font) error {
return nil
}

//BinaryEncoding encodes an image to PNG and returns a byte slice.
// BinaryEncoding encodes an image to PNG and returns a byte slice.
func (item *ItemChar) BinaryEncoding() []byte {
var buf bytes.Buffer
if err := png.Encode(&buf, item.nrgba); err != nil {
Expand Down
8 changes: 4 additions & 4 deletions item_digit.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type ItemDigit struct {
//rng siprng
}

//NewItemDigit create a instance of item-digit
// NewItemDigit create a instance of item-digit
func NewItemDigit(width int, height int, dotCount int, maxSkew float64) *ItemDigit {
itemDigit := &ItemDigit{width: width, height: height, dotCount: dotCount, maxSkew: maxSkew}
//init image.Paletted
Expand Down Expand Up @@ -157,13 +157,13 @@ func (m *ItemDigit) strikeThrough() {
yo := amplitude * math.Sin(float64(x)*dx)
for yn := 0; yn < m.dotSize; yn++ {
//r := m.rng.Int(0, m.dotSize)
r := rand.Intn(m.dotSize)
r := randIntn(m.dotSize)
m.drawCircle(x+int(xo), y+int(yo)+(yn*m.dotSize), r/2, 1)
}
}
}

//draw digit
// draw digit
func (m *ItemDigit) drawDigit(digit []byte, x, y int) {
skf := randFloat64Range(-m.maxSkew, m.maxSkew)
xs := float64(x)
Expand Down Expand Up @@ -205,7 +205,7 @@ func randomBrightness(c color.RGBA, max uint8) color.RGBA {
if maxc > max {
return c
}
n := rand.Intn(int(max-maxc)) - int(minc)
n := randIntn(int(max-maxc)) - int(minc)
return color.RGBA{
uint8(int(c.R) + n),
uint8(int(c.G) + n),
Expand Down
10 changes: 10 additions & 0 deletions randIntn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package base64Captcha

import "math/rand"

func randIntn(n int) int {
if n > 0 {
return rand.Intn(n)
}
return 0
}