diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba077a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bin diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..768b912 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +.PHONY: default b build i install r release + +default: build + +b build: + go build + +i install: + go install + +r release: + mkdir -p bin + CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o bin/genpno-macos-arm64 + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/genpno-linux-amd64 + CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -o bin/genpno-linux-386 + CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o bin/genpno-windows-amd64.exe + CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -o bin/genpno-windows-386.exe diff --git a/README.md b/README.md new file mode 100644 index 0000000..6afe4e5 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# Swedish Personnummer Generator + +A simple command-line interface (CLI) application written in Go that generates valid [Swedish "Personnummer" (personal identification numbers)](https://en.wikipedia.org/wiki/Personal_identity_number_(Sweden)). + +## Usage + +a) Download the binary from the releases page or + +b) Build the binary from source +```bash +go install github.com/dominikwinter/genpno@latest + +genpno +``` + +## Development + +1. Clone the repository: + +```bash +git clone https://github.com/dominikwinter/genpno.git +``` + +2. Navigate to the project directory: + +```bash +cd genpno +``` + +3. Build and install the application: + +```bash +make +make install +``` + +4. Run the application: + +```bash +genpno +``` + +## Features + +- **Easy to Use:** Simply execute the binary in the CLI to generate a valid Swedish "Personnummer." +- **Planned Flags:** Future updates will include optional flags to specify gender, birthdate, and output format. + +## How to Contribute + +If you'd like to contribute to the project, feel free to fork the repository and submit a pull request. Contributions are welcome! + + +## License + +This project is licensed under the [MIT License](LICENSE). diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2c13fde --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module genpno + +go 1.21.6 diff --git a/main.go b/main.go new file mode 100644 index 0000000..9fd9cb9 --- /dev/null +++ b/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "fmt" + "math/rand" + "strconv" + "time" +) + +func main() { + date := getRandomDate() + three := getRandomThreeDigits(true) + checksum := getChecksum(&date, &three) + + fmt.Println(date + three + checksum) +} + +func getRandomDate() string { + now := time.Now() + + min := now.AddDate(-100, 0, 0).Unix() + max := now.AddDate(-18, 0, 0).Unix() + + delta := max - min + sec := rand.Int63n(delta) + min + + return time.Unix(sec, 0).Format("20060102") +} + +func getRandomThreeDigits(male bool) string { + two := rand.Intn(99) + one := rand.Intn(9) + + var last int + + if male { + if one%2 == 1 { + last = one + } else { + last = (one + 1) % 10 + } + } else { + if one%2 == 0 { + last = one + } else { + last = (one + 1) % 10 + } + } + + return fmt.Sprintf("%02d%d", two, last) +} + +func getChecksum(date *string, three *string) string { + short_date := (*date)[len(*date)-6:] + short_checksum := short_date + *three + + sum := 0 + m := 2 + + for i := 0; i < len(short_checksum); i++ { + num, _ := strconv.Atoi(string(short_checksum[i])) + num = num * m + + if num >= 10 { + sum += (num % 10) + 1 + } else { + sum += num + } + + if m == 2 { + m = 1 + } else { + m = 2 + } + } + + checksum := 10 - (sum % 10) + + if checksum == 10 { + checksum = 0 + } + + return strconv.Itoa(checksum) +}