Skip to content

Commit

Permalink
Add new functions
Browse files Browse the repository at this point in the history
  • Loading branch information
goloop committed Jul 2, 2023
1 parent e2d1233 commit efd1a4c
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 0 deletions.
100 changes: 100 additions & 0 deletions hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package is

import (
"regexp"
"strings"
)

var (
Expand All @@ -18,6 +19,20 @@ var (
`[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`,
)

// The base64URLRegex is a regex pattern used to validate
// URL-safe Base64 encoded strings.
// It matches strings that:
// - consist of sequences of 4 valid URL-safe Base64 characters
// (A-Za-z0-9_-), repeated 0 or more times.
// - optionally, end with a sequence of 2 valid URL-safe Base64 characters
// followed by '==', or 3 valid URL-safe Base64 characters followed by
// '=', or 4 valid URL-safe Base64 characters.
base64URLRegex = regexp.MustCompile(
`^(?:[A-Za-z0-9_-]{4})*((?:[A-Za-z0-9_-]{2,4})|` +
`(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|` +
`[A-Za-z0-9+\\/]{4}))$`,
)

// The hexRegex is a regex pattern used to validate hexadecimal strings.
hexRegex = regexp.MustCompile(`^(#|0x)?[0-9a-fA-F]+$`)

Expand Down Expand Up @@ -65,6 +80,38 @@ func Base64(v string) bool {
return base64Regex.MatchString(v)
}

// Base64URL validates whether a given string 'v' is a valid URL-safe Base64
// encoded string.
//
// URL-safe Base64 encoding is similar to standard Base64 encoding, but it uses
// different characters to represent the encoded data, making it safe to use in
// URLs and filenames. The characters '+' and '/' in standard Base64 encoding
// are replaced with '-' and '_' respectively in URL-safe Base64 encoding.
// The padding character '=' is also used in URL-safe Base64 encoding.
//
// This function uses a regular expression to verify that the input string
// conforms to the format of a URL-safe Base64 encoded string. It checks if
// the string can be evenly divided by 4, and only contains valid URL-safe
// Base64 characters (A-Z, a-z, 0-9, -, and _ for padding). The padding at
// the end of URL-safe Base64 string, which is one or two '=' characters,
// is also checked for.
//
// If the input string matches this format, the function returns true,
// indicating that the string is a valid URL-safe Base64 encoded string.
// Otherwise, it returns false.
//
// Example usage:
//
// is.Base64URL("SGVsbG8sIHdvcmxkIQ") // Returns: true
// is.Base64URL("SGVsbG8sIHdvcmxkIQ==") // Returns: true
// is.Base64URL("SGVsbG8sIHdvcmxkIQ===") // Returns: false
//
// Note: This function does not validate the content of the encoded data,
// just the format of URL-safe Base64 strings.
func Base64URL(v string) bool {
return base64URLRegex.MatchString(v)
}

// Hex validates whether a given string 'v' is a valid hexadecimal value.
//
// A hexadecimal value is a number that includes digits from 0 to 9 and
Expand Down Expand Up @@ -180,3 +227,56 @@ func HexColor(v string) bool {
func RGBColor(v string) bool {
return rgbColorRegex.MatchString(v)
}

// JWT checks if the given string is a valid JSON Web Token (JWT).
// JWTs are used for securely transmitting information between parties
// as a JSON object. They consist of three parts: header, payload,
// and signature, separated by dots.
//
// This function validates the JWT by performing the following checks:
// 1. The input string should consist of three parts separated by dots.
// 2. Each part should be a valid Base64URL encoded string.
//
// If the input string passes these checks, the function returns true,
// indicating that the string is a valid JWT. Otherwise, it returns false.
//
// Example usage:
//
// is.JWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIi" +
// "wibWVzc2FnZSI6IkhlbGxvIFdvcmxkIiwiaWF0IjoxNTE2MjM5MDIyfQ.pfdTXv" +
// "HNIobiLJJ1MoiNyuzf5ZaUCpMu889Q8AJaWjs") // Returns: true
// is.JWT("notajwt") // Returns: false
func JWT(v string) bool {
parts := strings.Split(v, ".")
if len(parts) != 3 {
return false
}

for _, part := range parts {
if !Base64URL(part) {
return false
}
}

return true
}

// MD5 checks if the given string is a valid MD5 hash.
// MD5 is a widely used cryptographic hash function that produces
// a 128-bit (16-byte) hash value. It is commonly used to verify
// data integrity and to store passwords.
//
// This function validates the MD5 hash by performing the following checks:
// 1. The input string should consist of exactly 32 characters.
// 2. Each character should be a valid hexadecimal digit (0-9, a-f, A-F).
//
// If the input string passes these checks, the function returns true,
// indicating that the string is a valid MD5 hash. Otherwise, it returns false.
//
// Example usage:
//
// is.MD5("d41d8cd98f00b204e9800998ecf8427e") // Returns: true
// is.MD5("notamd5hash") // Returns: false
func MD5(v string) bool {
return len(v) == 32 && Hex(v)
}
66 changes: 66 additions & 0 deletions hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ func TestBase64(t *testing.T) {
}
}

// TestBase64URL tests Base64URL function.
func TestBase64URL(t *testing.T) {
validBase64URL := "SGVsbG8sIHdvcmxkIQ"
invalidBase64URL := "notabase64url"

validResult := Base64URL(validBase64URL)
if !validResult {
t.Errorf("Expected valid Base64URL to return true, got false")
}

invalidResult := Base64URL(invalidBase64URL)
if invalidResult {
t.Errorf("Expected invalid Base64URL to return false, got true")
}
}

// TestHex tests Hex function.
func TestHex(t *testing.T) {
tests := []struct {
Expand Down Expand Up @@ -230,3 +246,53 @@ func TestBin(t *testing.T) {
})
}
}

// TestJWT tests JWT function.
func TestJWT(t *testing.T) {
tests := []struct {
name string
in string
want bool
}{
{
name: "Valid JWT with secret base64 encoded",
in: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibWVzc2FnZSI6IlJ1c3NpYW5zIGFyZSBtYW5pYWNzIGFuZCBmcmVha3MiLCJpYXQiOjE1MTYyMzkwMjJ9.3tG1rYCCxE7umetsvJPEYAZWCMQy-uwY5hA7QGvVqnM",
want: true,
},
{
name: "Valid JWT",
in: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibWVzc2FnZSI6IlB1dGluIGlzIGFic29sdXRlIHNoaXQiLCJpYXQiOjE1MTYyMzkwMjJ9.wkLWA5GtCpWdxNOrRse8yHZgORDgf8TpJp73WUQb910",
want: true,
},
{
name: "Not valid JWT",
in: "eyHHGJHgJciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ZSI6IlB1dGl",
want: false,
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
got := JWT(tc.in)
if got != tc.want {
t.Errorf("JWT(%q) = %v; want %v", tc.in, got, tc.want)
}
})
}
}

// TestMD5 tests MD5 function.
func TestMD5(t *testing.T) {
validMD5 := "d41d8cd98f00b204e9800998ecf8427e"
invalidMD5 := "notamd5hash"

validResult := MD5(validMD5)
if !validResult {
t.Errorf("Expected valid MD5 to return true, got false")
}

invalidResult := MD5(invalidMD5)
if invalidResult {
t.Errorf("Expected invalid MD5 to return false, got true")
}
}

0 comments on commit efd1a4c

Please sign in to comment.