Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
498785e213
|
|||
678f95642c
|
|||
dacc97e2ce
|
|||
f8c0c0afa0
|
|||
2fbd5cf965
|
@@ -5,8 +5,8 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/format"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext"
|
"gogs.mikescher.com/BlackForestBytes/goext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/cmdext"
|
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/cryptext"
|
"gogs.mikescher.com/BlackForestBytes/goext/cryptext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/rext"
|
"gogs.mikescher.com/BlackForestBytes/goext/rext"
|
||||||
@@ -17,7 +17,6 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type CSIDDef struct {
|
type CSIDDef struct {
|
||||||
@@ -101,25 +100,16 @@ func GenerateCharsetIDSpecs(sourceDir string, destFile string) error {
|
|||||||
return errors.New("no package name found in any file")
|
return errors.New("no package name found in any file")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.WriteFile(destFile, []byte(fmtCSIDOutput(newChecksum, allIDs, pkgname)), 0o755)
|
fdata, err := format.Source([]byte(fmtCSIDOutput(newChecksum, allIDs, pkgname)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := cmdext.RunCommand("go", []string{"fmt", destFile}, langext.Ptr(2*time.Second))
|
err = os.WriteFile(destFile, fdata, 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.CommandTimedOut {
|
|
||||||
fmt.Println(res.StdCombined)
|
|
||||||
return errors.New("go fmt timed out")
|
|
||||||
}
|
|
||||||
if res.ExitCode != 0 {
|
|
||||||
fmt.Println(res.StdCombined)
|
|
||||||
return errors.New("go fmt did not succeed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
package {{.PkgName}}
|
package {{.PkgName}}
|
||||||
|
|
||||||
import "crypto/rand"
|
import "crypto/rand"
|
||||||
|
import "crypto/sha256"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "github.com/go-playground/validator/v10"
|
import "github.com/go-playground/validator/v10"
|
||||||
import "github.com/rs/zerolog/log"
|
import "github.com/rs/zerolog/log"
|
||||||
@@ -65,6 +66,27 @@ func generateID(prefix string) string {
|
|||||||
return prefix + k + checkstr
|
return prefix + k + checkstr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateIDFromSeed(prefix string, seed string) string {
|
||||||
|
h := sha256.New()
|
||||||
|
|
||||||
|
iddata := ""
|
||||||
|
for len(iddata) < idlen-len(prefix)-checklen {
|
||||||
|
h.Write([]byte(seed))
|
||||||
|
bs := h.Sum(nil)
|
||||||
|
iddata += langext.NewAnyBaseConverter(idCharset).Encode(bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum := 0
|
||||||
|
for i := 0; i < idlen-len(prefix)-checklen; i++ {
|
||||||
|
ichr := int(iddata[i])
|
||||||
|
checksum = (checksum + charSetReverseMap[ichr]) % (idCharsetLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkstr := string(idCharset[checksum%idCharsetLen])
|
||||||
|
|
||||||
|
return prefix + iddata[:(idlen-len(prefix)-checklen)] + checkstr
|
||||||
|
}
|
||||||
|
|
||||||
func validateID(prefix string, value string) error {
|
func validateID(prefix string, value string) error {
|
||||||
if len(value) != idlen {
|
if len(value) != idlen {
|
||||||
return exerr.New(exerr.TypeInvalidCSID, "id has the wrong length").Str("value", value).Build()
|
return exerr.New(exerr.TypeInvalidCSID, "id has the wrong length").Str("value", value).Build()
|
||||||
|
@@ -5,8 +5,8 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/format"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext"
|
"gogs.mikescher.com/BlackForestBytes/goext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/cmdext"
|
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/cryptext"
|
"gogs.mikescher.com/BlackForestBytes/goext/cryptext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/rext"
|
"gogs.mikescher.com/BlackForestBytes/goext/rext"
|
||||||
@@ -17,7 +17,6 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type EnumDefVal struct {
|
type EnumDefVal struct {
|
||||||
@@ -110,25 +109,16 @@ func GenerateEnumSpecs(sourceDir string, destFile string) error {
|
|||||||
return errors.New("no package name found in any file")
|
return errors.New("no package name found in any file")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.WriteFile(destFile, []byte(fmtEnumOutput(newChecksum, allEnums, pkgname)), 0o755)
|
fdata, err := format.Source([]byte(fmtEnumOutput(newChecksum, allEnums, pkgname)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := cmdext.RunCommand("go", []string{"fmt", destFile}, langext.Ptr(2*time.Second))
|
err = os.WriteFile(destFile, fdata, 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.CommandTimedOut {
|
|
||||||
fmt.Println(res.StdCombined)
|
|
||||||
return errors.New("go fmt timed out")
|
|
||||||
}
|
|
||||||
if res.ExitCode != 0 {
|
|
||||||
fmt.Println(res.StdCombined)
|
|
||||||
return errors.New("go fmt did not succeed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,8 +5,8 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/format"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext"
|
"gogs.mikescher.com/BlackForestBytes/goext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/cmdext"
|
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/cryptext"
|
"gogs.mikescher.com/BlackForestBytes/goext/cryptext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/rext"
|
"gogs.mikescher.com/BlackForestBytes/goext/rext"
|
||||||
@@ -17,7 +17,6 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IDDef struct {
|
type IDDef struct {
|
||||||
@@ -100,25 +99,16 @@ func GenerateIDSpecs(sourceDir string, destFile string) error {
|
|||||||
return errors.New("no package name found in any file")
|
return errors.New("no package name found in any file")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.WriteFile(destFile, []byte(fmtIDOutput(newChecksum, allIDs, pkgname)), 0o755)
|
fdata, err := format.Source([]byte(fmtIDOutput(newChecksum, allIDs, pkgname)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := cmdext.RunCommand("go", []string{"fmt", destFile}, langext.Ptr(2*time.Second))
|
err = os.WriteFile(destFile, fdata, 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.CommandTimedOut {
|
|
||||||
fmt.Println(res.StdCombined)
|
|
||||||
return errors.New("go fmt timed out")
|
|
||||||
}
|
|
||||||
if res.ExitCode != 0 {
|
|
||||||
fmt.Println(res.StdCombined)
|
|
||||||
return errors.New("go fmt did not succeed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -66,7 +66,6 @@ func (ph PassHash) Data() (_version int, _seed []byte, _payload []byte, _totp bo
|
|||||||
return int(version), nil, payload, false, nil, true
|
return int(version), nil, payload, false, nil, true
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
if version == 2 {
|
if version == 2 {
|
||||||
if len(split) != 3 {
|
if len(split) != 3 {
|
||||||
return -1, nil, nil, false, nil, false
|
return -1, nil, nil, false, nil, false
|
||||||
|
@@ -1,12 +1,15 @@
|
|||||||
package ginext
|
package ginext
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/dataext"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
|
"io"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -17,6 +20,7 @@ type PreContext struct {
|
|||||||
uri any
|
uri any
|
||||||
query any
|
query any
|
||||||
body any
|
body any
|
||||||
|
rawbody *[]byte
|
||||||
form any
|
form any
|
||||||
header any
|
header any
|
||||||
timeout *time.Duration
|
timeout *time.Duration
|
||||||
@@ -37,6 +41,11 @@ func (pctx *PreContext) Body(body any) *PreContext {
|
|||||||
return pctx
|
return pctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pctx *PreContext) RawBody(rawbody *[]byte) *PreContext {
|
||||||
|
pctx.rawbody = rawbody
|
||||||
|
return pctx
|
||||||
|
}
|
||||||
|
|
||||||
func (pctx *PreContext) Form(form any) *PreContext {
|
func (pctx *PreContext) Form(form any) *PreContext {
|
||||||
pctx.form = form
|
pctx.form = form
|
||||||
return pctx
|
return pctx
|
||||||
@@ -90,6 +99,23 @@ func (pctx PreContext) Start() (*AppContext, *gin.Context, *HTTPResponse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pctx.rawbody != nil {
|
||||||
|
if brc, ok := pctx.ginCtx.Request.Body.(dataext.BufferedReadCloser); ok {
|
||||||
|
v, err := brc.BufferedAll()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, langext.Ptr(Error(err))
|
||||||
|
}
|
||||||
|
*pctx.rawbody = v
|
||||||
|
} else {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
_, err := io.Copy(buf, pctx.ginCtx.Request.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, langext.Ptr(Error(err))
|
||||||
|
}
|
||||||
|
*pctx.rawbody = buf.Bytes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if pctx.form != nil {
|
if pctx.form != nil {
|
||||||
if pctx.ginCtx.ContentType() == "multipart/form-data" {
|
if pctx.ginCtx.ContentType() == "multipart/form-data" {
|
||||||
if err := pctx.ginCtx.ShouldBindWith(pctx.form, binding.Form); err != nil {
|
if err := pctx.ginCtx.ShouldBindWith(pctx.form, binding.Form); err != nil {
|
||||||
|
2
go.mod
2
go.mod
@@ -16,7 +16,7 @@ require (
|
|||||||
require (
|
require (
|
||||||
github.com/bytedance/sonic v1.10.2 // indirect
|
github.com/bytedance/sonic v1.10.2 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||||
github.com/chenzhuoyu/iasm v0.9.0 // indirect
|
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
2
go.sum
2
go.sum
@@ -8,6 +8,8 @@ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ
|
|||||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||||
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
|
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
|
||||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||||
|
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
|
||||||
|
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
package goext
|
package goext
|
||||||
|
|
||||||
const GoextVersion = "0.0.294"
|
const GoextVersion = "0.0.299"
|
||||||
|
|
||||||
const GoextVersionTimestamp = "2023-10-31T22:58:28+0100"
|
const GoextVersionTimestamp = "2023-11-03T16:53:41+0100"
|
||||||
|
178
langext/baseAny.go
Normal file
178
langext/baseAny.go
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
package langext
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
|
"math"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AnyBaseConverter struct {
|
||||||
|
base uint64
|
||||||
|
charset []rune
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAnyBaseConverter(cs string) AnyBaseConverter {
|
||||||
|
rcs := []rune(cs)
|
||||||
|
return AnyBaseConverter{
|
||||||
|
base: uint64(len(rcs)),
|
||||||
|
charset: rcs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc AnyBaseConverter) Rand(rlen int) string {
|
||||||
|
biBase := big.NewInt(int64(bc.base))
|
||||||
|
|
||||||
|
randMax := big.NewInt(math.MaxInt64)
|
||||||
|
|
||||||
|
r := ""
|
||||||
|
|
||||||
|
for i := 0; i < rlen; i++ {
|
||||||
|
v, err := rand.Int(rand.Reader, randMax)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r += string(bc.charset[v.Mod(v, biBase).Int64()])
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc AnyBaseConverter) EncodeUInt64(num uint64) string {
|
||||||
|
if num == 0 {
|
||||||
|
return "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
b := ""
|
||||||
|
|
||||||
|
// loop as long the num is bigger than zero
|
||||||
|
for num > 0 {
|
||||||
|
r := num % bc.base
|
||||||
|
|
||||||
|
num -= r
|
||||||
|
num /= base62Base
|
||||||
|
|
||||||
|
b += string(bc.charset[int(r)])
|
||||||
|
}
|
||||||
|
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc AnyBaseConverter) DecodeUInt64(str string) (uint64, error) {
|
||||||
|
if str == "" {
|
||||||
|
return 0, errors.New("empty string")
|
||||||
|
}
|
||||||
|
|
||||||
|
result := uint64(0)
|
||||||
|
|
||||||
|
for _, v := range str {
|
||||||
|
result *= base62Base
|
||||||
|
|
||||||
|
pos := ArrFirstIndex(bc.charset, v)
|
||||||
|
if pos == -1 {
|
||||||
|
return 0, errors.New("invalid character: " + string(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
result += uint64(pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc AnyBaseConverter) Encode(src []byte) string {
|
||||||
|
value := new(big.Int)
|
||||||
|
value.SetBytes(src)
|
||||||
|
return bc.EncodeBigInt(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc AnyBaseConverter) EncodeBigInt(src *big.Int) string {
|
||||||
|
value := new(big.Int)
|
||||||
|
value.Set(src)
|
||||||
|
|
||||||
|
isneg := value.Sign() < 0
|
||||||
|
|
||||||
|
answer := ""
|
||||||
|
|
||||||
|
if isneg {
|
||||||
|
value.Neg(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
biBase := big.NewInt(int64(bc.base))
|
||||||
|
|
||||||
|
rem := new(big.Int)
|
||||||
|
|
||||||
|
for value.Sign() > 0 {
|
||||||
|
value.QuoRem(value, biBase, rem)
|
||||||
|
answer = string(bc.charset[rem.Int64()]) + answer
|
||||||
|
}
|
||||||
|
|
||||||
|
if isneg {
|
||||||
|
return "-" + answer
|
||||||
|
} else {
|
||||||
|
return answer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc AnyBaseConverter) Decode(src string) ([]byte, error) {
|
||||||
|
value, err := bc.DecodeToBigInt(src)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return value.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc AnyBaseConverter) DecodeToBigInt(_src string) (*big.Int, error) {
|
||||||
|
result := new(big.Int)
|
||||||
|
result.SetInt64(0)
|
||||||
|
|
||||||
|
src := []rune(_src)
|
||||||
|
|
||||||
|
if len(src) == 0 {
|
||||||
|
return nil, errors.New("string is empty")
|
||||||
|
}
|
||||||
|
if bc.base < 2 {
|
||||||
|
return nil, errors.New("not enough digits")
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
sign := new(big.Int)
|
||||||
|
sign.SetInt64(1)
|
||||||
|
if src[i] == '+' {
|
||||||
|
i++
|
||||||
|
} else if src[i] == '-' {
|
||||||
|
i++
|
||||||
|
sign.SetInt64(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if i >= len(src) {
|
||||||
|
return nil, errors.New("no digits in input")
|
||||||
|
}
|
||||||
|
|
||||||
|
biBase := big.NewInt(int64(bc.base))
|
||||||
|
|
||||||
|
oldResult := new(big.Int)
|
||||||
|
|
||||||
|
for ; i < len(src); i++ {
|
||||||
|
n := ArrFirstIndex(bc.charset, src[i])
|
||||||
|
if n < 0 {
|
||||||
|
return nil, errors.New("invalid characters in input")
|
||||||
|
}
|
||||||
|
|
||||||
|
oldResult.Set(result)
|
||||||
|
|
||||||
|
result.Mul(result, biBase)
|
||||||
|
result.Add(result, big.NewInt(int64(n)))
|
||||||
|
|
||||||
|
if result.Cmp(oldResult) < 0 {
|
||||||
|
return nil, errors.New("overflow")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if sign.Cmp(big.NewInt(0)) < 0 {
|
||||||
|
result.Neg(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
80
langext/baseAny_test.go
Normal file
80
langext/baseAny_test.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package langext
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/tst"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func _anyEncStr(bc AnyBaseConverter, v string) string {
|
||||||
|
vr := bc.Encode([]byte(v))
|
||||||
|
return vr
|
||||||
|
}
|
||||||
|
|
||||||
|
func _anyDecStr(bc AnyBaseConverter, v string) string {
|
||||||
|
vr, err := bc.Decode(v)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return string(vr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyBase58DefaultEncoding(t *testing.T) {
|
||||||
|
tst.AssertEqual(t, _anyEncStr(NewAnyBaseConverter("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"), "Hello"), "9Ajdvzr")
|
||||||
|
tst.AssertEqual(t, _anyEncStr(NewAnyBaseConverter("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"), "If debugging is the process of removing software bugs, then programming must be the process of putting them in."), "48638SMcJuah5okqPx4kCVf5d8QAdgbdNf28g7ReY13prUENNbMyssjq5GjsrJHF5zeZfqs4uJMUJHr7VbrU4XBUZ2Fw9DVtqtn9N1eXucEWSEZahXV6w4ysGSWqGdpeYTJf1MdDzTg8vfcQViifJjZX")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyBase58DefaultDecoding(t *testing.T) {
|
||||||
|
tst.AssertEqual(t, _anyDecStr(NewAnyBaseConverter("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"), "9Ajdvzr"), "Hello")
|
||||||
|
tst.AssertEqual(t, _anyDecStr(NewAnyBaseConverter("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"), "48638SMcJuah5okqPx4kCVf5d8QAdgbdNf28g7ReY13prUENNbMyssjq5GjsrJHF5zeZfqs4uJMUJHr7VbrU4XBUZ2Fw9DVtqtn9N1eXucEWSEZahXV6w4ysGSWqGdpeYTJf1MdDzTg8vfcQViifJjZX"), "If debugging is the process of removing software bugs, then programming must be the process of putting them in.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyBaseDecode(t *testing.T) {
|
||||||
|
|
||||||
|
const (
|
||||||
|
Binary = "01"
|
||||||
|
Decimal = "0123456789"
|
||||||
|
Hex = "0123456789ABCDEF"
|
||||||
|
DNA = "ACGT"
|
||||||
|
Base32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
||||||
|
Base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||||
|
Base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||||
|
Base256 = "🚀🪐☄🛰🌌🌑🌒🌓🌔🌕🌖🌗🌘🌍🌏🌎🐉☀💻🖥💾💿😂❤😍🤣😊🙏💕😭😘👍😅👏😁🔥🥰💔💖💙😢🤔😆🙄💪😉☺👌🤗💜😔😎😇🌹🤦🎉💞✌✨🤷😱😌🌸🙌😋💗💚😏💛🙂💓🤩😄😀🖤😃💯🙈👇🎶😒🤭❣😜💋👀😪😑💥🙋😞😩😡🤪👊🥳😥🤤👉💃😳✋😚😝😴🌟😬🙃🍀🌷😻😓⭐✅🥺🌈😈🤘💦✔😣🏃💐☹🎊💘😠☝😕🌺🎂🌻😐🖕💝🙊😹🗣💫💀👑🎵🤞😛🔴😤🌼😫⚽🤙☕🏆🤫👈😮🙆🍻🍃🐶💁😲🌿🧡🎁⚡🌞🎈❌✊👋😰🤨😶🤝🚶💰🍓💢🤟🙁🚨💨🤬✈🎀🍺🤓😙💟🌱😖👶🥴▶➡❓💎💸⬇😨🌚🦋😷🕺⚠🙅😟😵👎🤲🤠🤧📌🔵💅🧐🐾🍒😗🤑🌊🤯🐷☎💧😯💆👆🎤🙇🍑❄🌴💣🐸💌📍🥀🤢👅💡💩👐📸👻🤐🤮🎼🥵🚩🍎🍊👼💍📣🥂"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestDef struct {
|
||||||
|
FromCS string
|
||||||
|
FromVal string
|
||||||
|
ToCS string
|
||||||
|
ToVal string
|
||||||
|
}
|
||||||
|
|
||||||
|
defs := []TestDef{
|
||||||
|
{Binary, "10100101011100000101010", Decimal, "5421098"},
|
||||||
|
{Decimal, "5421098", DNA, "CCAGGTGAAGGG"},
|
||||||
|
{Decimal, "5421098", DNA, "CCAGGTGAAGGG"},
|
||||||
|
{Decimal, "80085", Base256, "🪐💞🔵"},
|
||||||
|
{Hex, "48656C6C6C20576F526C5421", Base64, "SGVsbGwgV29SbFQh"},
|
||||||
|
{Base64, "SGVsbGw/gV29SbF+Qh", Base32, "CIMVWGY3B7QFO32SNRPZBB"},
|
||||||
|
{Base64, "SGVsbGw/gV29SbF+Qh", Base58, "2fUsGKQUcgQcwSqpvy6"},
|
||||||
|
{Base64, "SGVsbGw/gV29SbF+Qh", Base62, "V34nvybdQ3m3RHk9Sr"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, def := range defs {
|
||||||
|
|
||||||
|
d1 := NewAnyBaseConverter(def.FromCS)
|
||||||
|
d2 := NewAnyBaseConverter(def.ToCS)
|
||||||
|
|
||||||
|
v1 := tst.Must(d1.Decode(def.FromVal))(t)
|
||||||
|
v2 := tst.Must(d2.Decode(def.ToVal))(t)
|
||||||
|
|
||||||
|
tst.AssertArrayEqual(t, v1, v2)
|
||||||
|
|
||||||
|
str2 := d2.Encode(v1)
|
||||||
|
tst.AssertEqual(t, str2, def.ToVal)
|
||||||
|
|
||||||
|
str1 := d1.Encode(v2)
|
||||||
|
tst.AssertEqual(t, str1, def.FromVal)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -14,6 +14,20 @@ func AssertEqual[T comparable](t *testing.T, actual T, expected T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AssertArrayEqual[T comparable](t *testing.T, actual []T, expected []T) {
|
||||||
|
t.Helper()
|
||||||
|
if len(actual) != len(expected) {
|
||||||
|
t.Errorf("values differ: Actual: '%v', Expected: '%v' (len %d <> %d)", actual, expected, len(actual), len(expected))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := 0; i < len(actual); i++ {
|
||||||
|
if actual[i] != expected[i] {
|
||||||
|
t.Errorf("values differ: Actual: '%v', Expected: '%v' (at index %d)", actual, expected, i)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func AssertNotEqual[T comparable](t *testing.T, actual T, expected T) {
|
func AssertNotEqual[T comparable](t *testing.T, actual T, expected T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if actual == expected {
|
if actual == expected {
|
||||||
|
Reference in New Issue
Block a user