rewriting #1
53
build.sh
Executable file
53
build.sh
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
MAKE_PACKAGE=false
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 [OPTIONS]"
|
||||||
|
echo "Options:"
|
||||||
|
echo " --package Make a delivery package instead of plain binary"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to handle options and arguments
|
||||||
|
handle_options() {
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
--package)
|
||||||
|
MAKE_PACKAGE=true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid option: $1" >&2
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main script execution
|
||||||
|
handle_options "$@"
|
||||||
|
|
||||||
|
if [ ! -d "./build" ]; then
|
||||||
|
mkdir ./build
|
||||||
|
fi
|
||||||
|
|
||||||
|
platforms=("linux/386" "linux/amd64" "linux/arm64" "linux/riscv64" "darwin/arm64" "windows/arm64" "windows/amd64" "freebsd/amd64" "android/arm64")
|
||||||
|
|
||||||
|
for platform in "${platforms[@]}"; do
|
||||||
|
echo "* Compiling for $platform..."
|
||||||
|
platform_split=(${platform//\// })
|
||||||
|
|
||||||
|
EXT=""
|
||||||
|
if [ "${platform_split[0]}" == "windows" ]; then
|
||||||
|
EXT=.exe
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$MAKE_PACKAGE" == "true" ]; then
|
||||||
|
CGO_ENABLED=0 GOOS=${platform_split[0]} GOARCH=${platform_split[1]} go build -o build/hash_utils$EXT -a
|
||||||
|
tar -czf build/hash_utils_${platform_split[0]}_${platform_split[1]}.tar.gz build/hash_utils$EXT
|
||||||
|
rm build/hash_utils$EXT
|
||||||
|
else
|
||||||
|
CGO_ENABLED=0 GOOS=${platform_split[0]} GOARCH=${platform_split[1]} go build -o build/hash_utils_${platform_split[0]}_${platform_split[1]}$EXT -a
|
||||||
|
fi
|
||||||
|
done
|
||||||
102
commands/base64/base64.go
Normal file
102
commands/base64/base64.go
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package base64
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/subcommands"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Base64Cmd struct {
|
||||||
|
file string
|
||||||
|
decoderMode bool
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (*Base64Cmd) Name() string { return "base64" }
|
||||||
|
func (*Base64Cmd) Synopsis() string { return "" }
|
||||||
|
func (*Base64Cmd) Usage() string {
|
||||||
|
return `Usage: hash_utils base64
|
||||||
|
|
||||||
|
Options:
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Base64Cmd) SetFlags(f *flag.FlagSet) {
|
||||||
|
f.StringVar(&p.file, "file", "", "get the checksum of a file")
|
||||||
|
f.BoolVar(&p.decoderMode, "decode", false, "decode instead of encode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Base64Cmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
|
||||||
|
if p.decoderMode {
|
||||||
|
return p.decode(ctx, f, args)
|
||||||
|
}
|
||||||
|
return p.encode(ctx, f, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Base64Cmd) encode(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||||
|
if len(p.file) > 0 {
|
||||||
|
b, err := os.ReadFile(p.file)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "error: failed to open the file:", err)
|
||||||
|
return subcommands.ExitFailure
|
||||||
|
}
|
||||||
|
|
||||||
|
e := base64.NewEncoder(base64.RawStdEncoding, os.Stdout)
|
||||||
|
if _, err := e.Write(b); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "error:", err)
|
||||||
|
return subcommands.ExitFailure
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
return subcommands.ExitSuccess
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, arg := range f.Args() {
|
||||||
|
fmt.Print(arg, ": ")
|
||||||
|
e := base64.NewEncoder(base64.RawStdEncoding, os.Stdout)
|
||||||
|
if _, err := e.Write([]byte(arg)); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "error:", err)
|
||||||
|
return subcommands.ExitFailure
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
return subcommands.ExitSuccess
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Base64Cmd) decode(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||||
|
if len(p.file) > 0 {
|
||||||
|
file, err := os.OpenFile(p.file, os.O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "error: failed to open the file:", err)
|
||||||
|
return subcommands.ExitFailure
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
e := base64.NewDecoder(base64.RawStdEncoding, file)
|
||||||
|
if _, err := io.Copy(os.Stdout, e); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "error:", err)
|
||||||
|
return subcommands.ExitFailure
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
return subcommands.ExitSuccess
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, arg := range f.Args() {
|
||||||
|
r := strings.NewReader(arg)
|
||||||
|
e := base64.NewDecoder(base64.RawStdEncoding, r)
|
||||||
|
if _, err := io.Copy(os.Stdout, e); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "error:", err)
|
||||||
|
return subcommands.ExitFailure
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
return subcommands.ExitSuccess
|
||||||
|
}
|
||||||
@@ -3,32 +3,60 @@ package bcrypt
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/google/subcommands"
|
"github.com/google/subcommands"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
MD5Cmd struct {
|
BCryptCmd struct {
|
||||||
file string
|
cost int
|
||||||
round int
|
check bool
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (*MD5Cmd) Name() string { return "bcrypt" }
|
func (*BCryptCmd) Name() string { return "bcrypt" }
|
||||||
func (*MD5Cmd) Synopsis() string { return "" }
|
func (*BCryptCmd) Synopsis() string { return "" }
|
||||||
func (*MD5Cmd) Usage() string {
|
func (*BCryptCmd) Usage() string {
|
||||||
return `Usage: hash_utils bcrypt
|
return `Usage: hash_utils bcrypt
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MD5Cmd) SetFlags(f *flag.FlagSet) {
|
func (p *BCryptCmd) SetFlags(f *flag.FlagSet) {
|
||||||
f.StringVar(&p.file, "file", "", "get the checksum of a file")
|
f.IntVar(&p.cost, "cost", 12, "number of iteration")
|
||||||
f.IntVar(&p.round, "round", 12, "number of iteration")
|
f.BoolVar(&p.check, "check", false, "check a password")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MD5Cmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
func (p *BCryptCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||||
|
if p.check {
|
||||||
|
if f.NArg() != 2 {
|
||||||
|
fmt.Fprintln(os.Stderr, "error: invalid number of parameters")
|
||||||
|
return subcommands.ExitUsageError
|
||||||
|
}
|
||||||
|
if err := bcrypt.CompareHashAndPassword([]byte(f.Arg(0)), []byte(f.Arg(1))); err != nil {
|
||||||
|
fmt.Println("no match")
|
||||||
|
return subcommands.ExitSuccess
|
||||||
|
}
|
||||||
|
fmt.Println("match")
|
||||||
|
return subcommands.ExitSuccess
|
||||||
|
}
|
||||||
|
if p.cost < bcrypt.MinCost {
|
||||||
|
fmt.Fprintln(os.Stderr, "error: invalid cost settings: cost should be over", bcrypt.MinCost)
|
||||||
|
return subcommands.ExitUsageError
|
||||||
|
}
|
||||||
|
if p.cost > bcrypt.MaxCost {
|
||||||
|
fmt.Fprintln(os.Stderr, "error: invalid cost settings: cost should be under", bcrypt.MaxCost)
|
||||||
|
return subcommands.ExitUsageError
|
||||||
|
}
|
||||||
|
h, err := bcrypt.GenerateFromPassword([]byte(f.Arg(0)), p.cost)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "error:", err)
|
||||||
|
return subcommands.ExitFailure
|
||||||
|
}
|
||||||
|
fmt.Println(string(h))
|
||||||
return subcommands.ExitSuccess
|
return subcommands.ExitSuccess
|
||||||
}
|
}
|
||||||
|
|||||||
34
commands/version/version.go
Normal file
34
commands/version/version.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/google/subcommands"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
version string = "2.0.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
VersionCmd struct {
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (*VersionCmd) Name() string { return "version" }
|
||||||
|
func (*VersionCmd) Synopsis() string { return "" }
|
||||||
|
func (*VersionCmd) Usage() string {
|
||||||
|
return `Usage: hash_utils version
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *VersionCmd) SetFlags(f *flag.FlagSet) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *VersionCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||||
|
fmt.Printf("hash_utils %s %s/%s\n", version, runtime.GOOS, runtime.GOARCH)
|
||||||
|
return subcommands.ExitSuccess
|
||||||
|
}
|
||||||
1
go.mod
1
go.mod
@@ -5,4 +5,5 @@ go 1.24
|
|||||||
require (
|
require (
|
||||||
github.com/google/subcommands v1.2.0
|
github.com/google/subcommands v1.2.0
|
||||||
github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f
|
github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f
|
||||||
|
golang.org/x/crypto v0.41.0
|
||||||
)
|
)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -2,3 +2,5 @@ github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN
|
|||||||
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||||
github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f h1:1R9KdKjCNSd7F8iGTxIpoID9prlYH8nuNYKt0XvweHA=
|
github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f h1:1R9KdKjCNSd7F8iGTxIpoID9prlYH8nuNYKt0XvweHA=
|
||||||
github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f/go.mod h1:vQhwQ4meQEDfahT5kd61wLAF5AAeh5ZPLVI4JJ/tYo8=
|
github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f/go.mod h1:vQhwQ4meQEDfahT5kd61wLAF5AAeh5ZPLVI4JJ/tYo8=
|
||||||
|
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||||
|
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||||
|
|||||||
8
main.go
8
main.go
@@ -3,11 +3,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
|
"hash_utils/commands/base64"
|
||||||
|
"hash_utils/commands/bcrypt"
|
||||||
"hash_utils/commands/crc8"
|
"hash_utils/commands/crc8"
|
||||||
"hash_utils/commands/md5"
|
"hash_utils/commands/md5"
|
||||||
"hash_utils/commands/sha1"
|
"hash_utils/commands/sha1"
|
||||||
"hash_utils/commands/sha256"
|
"hash_utils/commands/sha256"
|
||||||
"hash_utils/commands/sha512"
|
"hash_utils/commands/sha512"
|
||||||
|
"hash_utils/commands/version"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/google/subcommands"
|
"github.com/google/subcommands"
|
||||||
@@ -17,6 +20,7 @@ func main() {
|
|||||||
subcommands.Register(subcommands.HelpCommand(), "help")
|
subcommands.Register(subcommands.HelpCommand(), "help")
|
||||||
subcommands.Register(subcommands.FlagsCommand(), "help")
|
subcommands.Register(subcommands.FlagsCommand(), "help")
|
||||||
subcommands.Register(subcommands.CommandsCommand(), "help")
|
subcommands.Register(subcommands.CommandsCommand(), "help")
|
||||||
|
subcommands.Register(&version.VersionCmd{}, "help")
|
||||||
|
|
||||||
subcommands.Register(&md5.MD5Cmd{}, "unkeyed cryptographic hash functions")
|
subcommands.Register(&md5.MD5Cmd{}, "unkeyed cryptographic hash functions")
|
||||||
subcommands.Register(&sha1.SHA1Cmd{}, "unkeyed cryptographic hash functions")
|
subcommands.Register(&sha1.SHA1Cmd{}, "unkeyed cryptographic hash functions")
|
||||||
@@ -25,6 +29,10 @@ func main() {
|
|||||||
|
|
||||||
subcommands.Register(&crc8.CRC8Cmd{}, "cyclic redundancy checks")
|
subcommands.Register(&crc8.CRC8Cmd{}, "cyclic redundancy checks")
|
||||||
|
|
||||||
|
subcommands.Register(&bcrypt.BCryptCmd{}, "password hashing functions")
|
||||||
|
|
||||||
|
subcommands.Register(&base64.Base64Cmd{}, "other")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user