Skip to content

Commit

Permalink
chore: restructured files - less ambiguous. Removed use of "utils"
Browse files Browse the repository at this point in the history
  • Loading branch information
nronzel committed Feb 12, 2024
1 parent 1e8d088 commit 7f9faf5
Show file tree
Hide file tree
Showing 20 changed files with 220 additions and 199 deletions.
30 changes: 30 additions & 0 deletions analysis/frequency.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package analysis

// scoreText evaluates the likelihood that a given byte slice (input) is
// meaningful or coherent English text. It does so by scoring each byte
// according to its frequency of appearance in English, with a higher score
// indicating a higher likelihood of the input being English.
func ScoreText(input []byte) float64 {
// englishFreq maps English letters and the space character to their
// relative frequencies in English text
englishFreq := map[byte]float64{
'a': 8.167, 'b': 1.492, 'c': 2.782, 'd': 4.253, 'e': 12.702,
'f': 2.228, 'g': 2.015, 'h': 6.094, 'i': 6.966, 'j': 0.153,
'k': 0.772, 'l': 4.025, 'm': 2.406, 'n': 6.749, 'o': 7.507,
'p': 1.929, 'q': 0.095, 'r': 5.987, 's': 6.327, 't': 9.056,
'u': 2.758, 'v': 0.978, 'w': 2.360, 'x': 0.150, 'y': 1.974,
'z': 0.074, ' ': 13.000,
}

score := 0.0

for _, b := range input {
// If the byte is found in the englishFreq map,add its frequency value
// to the total score.
if val, ok := englishFreq[b]; ok {
score += val
}
}

return score
}
27 changes: 27 additions & 0 deletions analysis/frequency_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package analysis

import (
"testing"
)

func TestScoreText(t *testing.T) {
tests := []struct {
name string
text string
score float64
}{
{name: "Valid score", text: "What Do You Want From Me", score: 158.66299999999998},
{name: "No text", text: "", score: 0.0},
{name: "Single letter", text: "a", score: 8.167},
{name: "Space", text: " ", score: 13.000},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ScoreText([]byte(tt.text))
if got != tt.score {
t.Fatalf("expected: %f, got: %f", tt.score, got)
}
})
}
}
19 changes: 19 additions & 0 deletions encoding/base64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package encoding

import "encoding/base64"

// Decodes Base64 encoded string. Returns bytes.
func DecodeBase64(encoded string) ([]byte, error) {
return base64.StdEncoding.DecodeString(encoded)
}

// isBase64Encoded checks if the input string is Base64 encoded.
// This function performs a basic check to see if the input is decodable from Base64.
func isBase64Encoded(input string) bool {
if input == "" {
return false
}
// Attempt to decode the input string from Base64
_, err := base64.StdEncoding.DecodeString(input)
return err == nil
}
24 changes: 24 additions & 0 deletions encoding/base64_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package encoding

import "testing"

func TestIsBase64Encoded(t *testing.T) {
tests := []struct {
name string
input string
want bool
}{
{name: "Valid Base64", input: "dGVzdCBpbnB1dA==", want: true},
{name: "Invalid Base64", input: "test input", want: false},
{name: "Empty String", input: "", want: false},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := isBase64Encoded(tt.input)
if got != tt.want {
t.Errorf("want: %v, got: %v", tt.want, got)
}
})
}
}
26 changes: 26 additions & 0 deletions encoding/decode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package encoding

func Decode(encodedData string) ([]byte, error) {
var verifiedData []byte
var err error
if isHexEncoded(encodedData) {
verifiedData, err = DecodeHex(encodedData)
if err != nil {
return nil, err
}
return verifiedData, nil
}

if isBase64Encoded(encodedData) {
verifiedData, err = DecodeBase64(encodedData)
if err != nil {
return nil, err
}
return verifiedData, nil
}

// plaintext, or some other encoded data type not checked for.
verifiedData = []byte(encodedData)

return verifiedData, nil
}
29 changes: 29 additions & 0 deletions encoding/decode_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package encoding

import "testing"

func TestDecode(t *testing.T) {
tests := []struct {
name string
encoded string
want string
wantErr bool
}{
{name: "Hex Encoded Text", encoded: "7465737420696e707574", want: "test input", wantErr: false},
{name: "Non-Encoded Text", encoded: "not encoded text", want: "not encoded text", wantErr: false},
{name: "Base64 Encoded Text", encoded: "dGVzdCBpbnB1dA==", want: "test input", wantErr: false},
{name: "Invalid Hex", encoded: "7465737420696e70757", want: "", wantErr: true},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Decode(tt.encoded)
if err == nil && tt.wantErr {
t.Errorf("expected error and didn't get one")
}
if string(got) != tt.want {
t.Errorf("want: %v, got: %v", tt.want, got)
}
})
}
}
28 changes: 28 additions & 0 deletions encoding/hex.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package encoding

import (
"encoding/hex"
"fmt"
"regexp"
)

// Decodes hex encoded string. Returns bytes.
func DecodeHex(encoded string) ([]byte, error) {
return hex.DecodeString(encoded)
}

// isHexEncoded checks if the input string is hex encoded.
// This function uses a regex pattern to ensure the string consists only of hexadecimal characters.
func isHexEncoded(input string) bool {
if input == "" {
return false
}
// Hex regex pattern to match valid hexadecimal characters
hexPattern := `^[0-9A-Fa-f]+$`
matched, err := regexp.MatchString(hexPattern, input)
if err != nil {
fmt.Println("Regex match error:", err)
return false
}
return matched
}
23 changes: 23 additions & 0 deletions encoding/hex_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package encoding

import "testing"

func TestIsHexEncoded(t *testing.T) {
tests := []struct {
name string
input string
want bool
}{
{name: "Valid Hex", input: "7465737420696e707574", want: true},
{name: "Invalid Hex", input: "test input", want: false},
{name: "Empty String", input: "", want: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := isHexEncoded(tt.input)
if got != tt.want {
t.Errorf("want: %v, got: %v", tt.want, got)
}
})
}
}
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"time"

"github.com/nronzel/xoracle/pkg/handlers"
limiter "github.com/nronzel/xoracle/pkg/rate_limiter"
mw "github.com/nronzel/xoracle/pkg/middleware"
)

func main() {
Expand All @@ -16,7 +16,7 @@ func main() {
mux.HandleFunc("GET /", handlers.HandlerRoot)
mux.HandleFunc("POST /decrypt", handlers.HandlerDecrypt)

rl := limiter.NewRateLimiter(1, 3)
rl := mw.NewRateLimiter(1, 3)

server := &http.Server{
Addr: ":8080",
Expand Down
5 changes: 3 additions & 2 deletions pkg/decryption/decryption.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package decryption

import (
"fmt"
"github.com/nronzel/xoracle/utils"
"math"
"sort"

"github.com/nronzel/xoracle/analysis"
)

// singleByteXORCipher attempts to decrypt a message that has been XOR'ed
Expand All @@ -30,7 +31,7 @@ func singleByteXORCipher(encoded []byte) (byte, []byte) {
}

// Evaluate the decrypted message using a scoring function.
score := utils.ScoreText(decoded)
score := analysis.ScoreText(decoded)

// If the current message's score is higher than the highest score found
// so far - update maxScore, key, and message with the current values.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions pkg/handlers/handlerDecrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"net/http"
"strings"

en "github.com/nronzel/xoracle/encoding"
dc "github.com/nronzel/xoracle/pkg/decryption"
"github.com/nronzel/xoracle/utils"
)

func HandlerDecrypt(w http.ResponseWriter, r *http.Request) {
Expand All @@ -23,7 +23,7 @@ func HandlerDecrypt(w http.ResponseWriter, r *http.Request) {
// Checks if data is Base64 or Hex encoded, and decodes, otherwise just
// returns the data as is. It's either plaintext, or some other encoding
// not checked for.
verifiedData, err := utils.Decode(encodedData)
verifiedData, err := en.Decode(encodedData)
if err != nil {
w.Header().Set("Content-Type", "text/plaintext")
http.Error(w, "problem decoding data", http.StatusInternalServerError)
Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions scripts/buildmac.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o xoracle-macos-amd64
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o xoracle-macos-arm64
3 changes: 3 additions & 0 deletions scripts/buildwindows.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o xoracle.exe
99 changes: 0 additions & 99 deletions utils/utils.go

This file was deleted.

Loading

0 comments on commit 7f9faf5

Please sign in to comment.