From 0e1425c1b9a4507028d2314f788cdb878db29a1c Mon Sep 17 00:00:00 2001 From: Fred Boniface Date: Fri, 1 Sep 2023 20:50:47 +0100 Subject: [PATCH] Implement creation --- .gitignore | 23 +++++++ generation/aztec.go | 28 +++++++++ generation/codabar.go | 16 +++++ generation/code128.go | 16 +++++ generation/code93.go | 16 +++++ generation/datamatrix.go | 16 +++++ generation/generate.go | 31 +++++++++ generation/qr.go | 28 +++++++++ generation/types.go | 29 +++++++++ go.mod | 2 + go.sum | 2 + main.go | 49 +++++++++++++++ strings/wifi.go | 1 + validation/charsets.go | 2 + validation/rules.go | 133 ++++++++++++++++++++------------------- validation/validate.go | 2 +- 16 files changed, 328 insertions(+), 66 deletions(-) create mode 100644 .gitignore create mode 100644 generation/aztec.go create mode 100644 generation/codabar.go create mode 100644 generation/code128.go create mode 100644 generation/code93.go create mode 100644 generation/datamatrix.go create mode 100644 generation/generate.go create mode 100644 generation/qr.go create mode 100644 generation/types.go create mode 100644 go.sum create mode 100644 main.go create mode 100644 strings/wifi.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c38fa71 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +*.png + +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work \ No newline at end of file diff --git a/generation/aztec.go b/generation/aztec.go new file mode 100644 index 0000000..f28e8fc --- /dev/null +++ b/generation/aztec.go @@ -0,0 +1,28 @@ +package generation + +import ( + "fmt" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/aztec" +) + +func generateAztec(parameters Parameters) (barcode.Barcode, error) { + var level uint8 + switch parameters.ECCLevel { + case 1: + level = 7 + case 2: + level = 15 + case 3: + level = 25 + case 4: + level = 30 + } + aztecCode, err := aztec.Encode([]byte(parameters.Content), int(level), 0) + if err != nil { + fmt.Println("Error creating Barcode", err) + } + + return aztecCode, err +} diff --git a/generation/codabar.go b/generation/codabar.go new file mode 100644 index 0000000..081a5e6 --- /dev/null +++ b/generation/codabar.go @@ -0,0 +1,16 @@ +package generation + +import ( + "fmt" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/codabar" +) + +func generateCodabar(parameters Parameters) (barcode.Barcode, error) { + codabar, err := codabar.Encode(parameters.Content) + if err != nil { + fmt.Println("Error creating Barcode", err) + } + return codabar, err +} diff --git a/generation/code128.go b/generation/code128.go new file mode 100644 index 0000000..a7f3893 --- /dev/null +++ b/generation/code128.go @@ -0,0 +1,16 @@ +package generation + +import ( + "fmt" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/code128" +) + +func generateCode128(parameters Parameters) (barcode.Barcode, error) { + barcode, err := code128.EncodeWithoutChecksum(parameters.Content) + if err != nil { + fmt.Println("Error creating Barcode", err) + } + return barcode, err +} diff --git a/generation/code93.go b/generation/code93.go new file mode 100644 index 0000000..69efb6c --- /dev/null +++ b/generation/code93.go @@ -0,0 +1,16 @@ +package generation + +import ( + "fmt" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/code93" +) + +func generateCode93(parameters Parameters) (barcode.Barcode, error) { + barcode, err := code93.Encode(parameters.Content, true, true) + if err != nil { + fmt.Println("Error creating Barcode", err) + } + return barcode, err +} diff --git a/generation/datamatrix.go b/generation/datamatrix.go new file mode 100644 index 0000000..358b991 --- /dev/null +++ b/generation/datamatrix.go @@ -0,0 +1,16 @@ +package generation + +import ( + "fmt" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/datamatrix" +) + +func generateDatamatrix(parameters Parameters) (barcode.Barcode, error) { + barcode, err := datamatrix.Encode(parameters.Content) + if err != nil { + fmt.Println("Error creating Barcode", err) + } + return barcode, err +} diff --git a/generation/generate.go b/generation/generate.go new file mode 100644 index 0000000..5a0a729 --- /dev/null +++ b/generation/generate.go @@ -0,0 +1,31 @@ +package generation + +import ( + "fmt" + + "github.com/boombuler/barcode" +) + +func Generate(parameters Parameters) (barcode.Barcode, error) { + var barcode_content barcode.Barcode + var err error + + switch parameters.Format { + case Aztec: + barcode_content, err = generateAztec(parameters) + case Codabar: + barcode_content, err = generateCodabar(parameters) + case Code93: + barcode_content, err = generateCode93(parameters) + case Code128: + barcode_content, err = generateCode128(parameters) + case QR: + barcode_content, err = generateQr(parameters) + case Datamatrix: + barcode_content, err = generateDatamatrix(parameters) + default: + fmt.Println("Unsupported barcode type: ", parameters.Format) + } + + return barcode_content, err +} diff --git a/generation/qr.go b/generation/qr.go new file mode 100644 index 0000000..aa29dca --- /dev/null +++ b/generation/qr.go @@ -0,0 +1,28 @@ +package generation + +import ( + "fmt" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/qr" +) + +func generateQr(parameters Parameters) (barcode.Barcode, error) { + var level qr.ErrorCorrectionLevel + switch parameters.ECCLevel { + case 1: + level = qr.L + case 2: + level = qr.M + case 3: + level = qr.Q + case 4: + level = qr.H + } + qrCode, err := qr.Encode(parameters.Content, level, qr.Auto) + if err != nil { + fmt.Println("Error creating Barcode", err) + } + + return qrCode, err +} diff --git a/generation/types.go b/generation/types.go new file mode 100644 index 0000000..38f3434 --- /dev/null +++ b/generation/types.go @@ -0,0 +1,29 @@ +package generation + +type BarcodeType string + +const ( + Aztec BarcodeType = "aztec" + Codabar BarcodeType = "codabar" + Code93 BarcodeType = "code93" + Code128 BarcodeType = "code128" + QR BarcodeType = "qr" + Datamatrix BarcodeType = "datamatrix" +) + +type ECCLevel int + +const ( + Low ECCLevel = 1 + Med ECCLevel = 2 + High ECCLevel = 3 + Max ECCLevel = 4 +) + +type Parameters struct { + Format BarcodeType + ECCLevel ECCLevel + Content string +} + +// diff --git a/go.mod b/go.mod index a82281d..0be6e4b 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module git.fjla.uk/fred.boniface/barcodes go 1.19 + +require github.com/boombuler/barcode v1.0.1 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d1dcbd8 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= diff --git a/main.go b/main.go new file mode 100644 index 0000000..2ef85fa --- /dev/null +++ b/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "flag" + "fmt" + "image/png" + "os" + + "github.com/boombuler/barcode" + + "git.fjla.uk/fred.boniface/barcodes/generation" + "git.fjla.uk/fred.boniface/barcodes/validation" +) + +func main() { + barcodeType := flag.String("type", "", "Barcode type (aztec, codabar, code93, code128, qr)") + content := flag.String("content", "", "Barcode content") + + flag.Parse() + + if *barcodeType == "" || *content == "" { + fmt.Println("Usage: ./barcodes --type --content ") + return + } + + fmt.Printf("Barcode Type: %s\n", *barcodeType) + fmt.Printf("Barcode Content: %s\n", *content) + + validation.Validate(*content, *barcodeType) + + parameters := generation.Parameters{ + Format: generation.BarcodeType(*barcodeType), + ECCLevel: generation.ECCLevel(3), + Content: *content, + } + + generated_barcode, err := generation.Generate(parameters) + if err != nil { + fmt.Println("Error: ", err) + os.Exit(1) + } + + generated_barcode, _ = barcode.Scale(generated_barcode, 200, 200) + + file, _ := os.Create("barcode.png") + defer file.Close() + png.Encode(file, generated_barcode) + +} diff --git a/strings/wifi.go b/strings/wifi.go new file mode 100644 index 0000000..e152b4b --- /dev/null +++ b/strings/wifi.go @@ -0,0 +1 @@ +package strings diff --git a/validation/charsets.go b/validation/charsets.go index 6dd485b..dcb4513 100644 --- a/validation/charsets.go +++ b/validation/charsets.go @@ -5,7 +5,9 @@ import "regexp" var ( ASCII = regexp.MustCompile(`^[\x00-\x7F]+$`) ANY = regexp.MustCompile(`.`) + CODABAR = regexp.MustCompile(`^[0-9-$:/.+]+$`) CODE39 = regexp.MustCompile(`^[0-9A-Z\-\.\ $%*+/]+$`) + CODE93 = regexp.MustCompile(`^[A-Za-z0-9\-.\$/\+%\s]+$`) NUMERAL = regexp.MustCompile(`^[0-9]+$`) ISO88591 = regexp.MustCompile(`^[\x00-\xFF]+$`) ) diff --git a/validation/rules.go b/validation/rules.go index 48e99b7..ba57304 100644 --- a/validation/rules.go +++ b/validation/rules.go @@ -11,79 +11,82 @@ type rule struct { divisible uint8 } -var aztec = rule{ - minLength: 1, - maxLength: 3067, - charset: *ANY, - divisible: 1, -} +var formatRules = map[string]rule{ -var code39 = rule{ - minLength: 1, - maxLength: 80, - charset: *CODE39, - divisible: 1, -} + "2of5": { + minLength: 2, + maxLength: 80, + charset: *NUMERAL, + divisible: 2, + }, -var code128 = rule{ - minLength: 1, - maxLength: 80, - charset: *ASCII, - divisible: 1, -} + "aztec": { + minLength: 1, + maxLength: 3067, + charset: *ANY, + divisible: 1, + }, -var datamatrix = rule{ - minLength: 1, - maxLength: 2335, - charset: *ANY, - divisible: 1, -} + "codabar": { + minLength: 1, + maxLength: 100, + charset: *CODABAR, + divisible: 1, + }, -var ean8 = rule{ - minLength: 7, - maxLength: 7, - charset: *NUMERAL, - divisible: 1, -} + "code39": { + minLength: 1, + maxLength: 80, + charset: *CODE39, + divisible: 1, + }, -var ean13 = rule{ - minLength: 12, - maxLength: 12, - charset: *NUMERAL, - divisible: 1, -} + "code93": { + minLength: 1, + maxLength: 80, + charset: *ASCII, + divisible: 1, + }, -var ean14 = rule{ - minLength: 2, - maxLength: 80, - charset: *NUMERAL, - divisible: 2, -} + "code128": { + minLength: 1, + maxLength: 80, + charset: *ASCII, + divisible: 1, + }, -var pdf417 = rule{ - minLength: 1, - maxLength: 1100, - charset: *ANY, - divisible: 1, -} + "datamatrix": { + minLength: 1, + maxLength: 2335, + charset: *ANY, + divisible: 1, + }, -var pzn7 = rule{ - minLength: 7, - maxLength: 7, - charset: *NUMERAL, - divisible: 1, -} + "ean8": { + minLength: 7, + maxLength: 7, + charset: *NUMERAL, + divisible: 1, + }, -var qr = rule{ - minLength: 1, - maxLength: 4296, - charset: *ISO88591, - divisible: 1, -} + "ean13": { + minLength: 12, + maxLength: 12, + charset: *NUMERAL, + divisible: 1, + }, -var upca = rule{ - minLength: 11, - maxLength: 11, - charset: *NUMERAL, - divisible: 1, + "pdf417": { + minLength: 1, + maxLength: 1100, + charset: *ANY, + divisible: 1, + }, + + "qr": { + minLength: 1, + maxLength: 4296, + charset: *ISO88591, + divisible: 1, + }, } diff --git a/validation/validate.go b/validation/validate.go index ca73a82..3a85818 100644 --- a/validation/validate.go +++ b/validation/validate.go @@ -3,7 +3,7 @@ package validation import "fmt" func Validate(input string, format string) bool { - rule, exists := barcodeRules[format] + rule, exists := formatRules[format] if !exists { fmt.Printf("Error: No rule found for format '%s'\n", format) return false