rewriting #1

Merged
thelilfrog merged 4 commits from rewriting into main 2025-08-11 23:53:02 +02:00
7 changed files with 239 additions and 11 deletions
Showing only changes of commit 4c8585781e - Show all commits

53
build.sh Executable file
View 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
View 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
}

View File

@@ -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
} }

View 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
View File

@@ -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
View File

@@ -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=

View File

@@ -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()