diff --git a/go.mod b/go.mod
index abf221bedeed80d015c6bd6fb5903903ece7e0f5..3078df486d1002222294654ddc48ae996090ae55 100644
--- a/go.mod
+++ b/go.mod
@@ -9,6 +9,7 @@ require (
 	github.com/aws/aws-lambda-go v1.26.0
 	github.com/aws/aws-sdk-go v1.44.180
 	github.com/aws/aws-secretsmanager-caching-go v1.1.0
+	github.com/dimuska139/go-email-normalizer/v2 v2.0.0
 	github.com/dlsniper/debugger v0.6.0
 	github.com/go-pg/pg/v10 v10.10.6
 	github.com/go-redis/redis/v8 v8.11.4
diff --git a/go.sum b/go.sum
index cc0f301dcc14c7b929620715cf24e3a075d18c44..23b6fdeeddde3ebd4f5f365881ddec3accbb5707 100644
--- a/go.sum
+++ b/go.sum
@@ -36,6 +36,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
+github.com/dimuska139/go-email-normalizer/v2 v2.0.0 h1:LH41ypO4BFast9bc8hNu6YEkRvLloHFYihSjfwiARSg=
+github.com/dimuska139/go-email-normalizer/v2 v2.0.0/go.mod h1:2Gil1j/rfUKJ5BHc/uxxyRiuk3YTg6/C3D7dz7jVQfw=
 github.com/dlsniper/debugger v0.6.0 h1:AyPoOtJviCmig9AKNRAPPw5B5UyB+cI72zY3Jb+6LlA=
 github.com/dlsniper/debugger v0.6.0/go.mod h1:FFdRcPU2Yo4P411bp5U97DHJUSUMKcqw1QMGUu0uVb8=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
diff --git a/utils/utils.go b/utils/utils.go
index d06280d87e868e0f216e2299c78316946dfb7fd1..526025d0dc8fb9c99ea18538ed963422039fed04 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -3,11 +3,13 @@ package utils
 import (
 	"bytes"
 	emailverifier "github.com/AfterShip/email-verifier"
+	normalizer "github.com/dimuska139/go-email-normalizer/v2"
 	"github.com/jinzhu/now"
 	"github.com/mohae/deepcopy"
 	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/errors"
 	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/string_utils"
 	"math"
+	"net"
 	"net/url"
 	"os"
 	"reflect"
@@ -149,6 +151,11 @@ func StripEmail(email string) (strippedEmail string, strippedDomain string) {
 	return strippedEmail, strippedDomain
 }
 
+func NormalizeEmail(email string) string {
+	emailNormalizer := normalizer.NewNormalizer()
+	return emailNormalizer.Normalize(email)
+}
+
 // IsUrlStrict Returns whether a URL is valid in a strict way (Must have scheme and host)
 func IsUrlStrict(str string) bool {
 	u, err := url.Parse(str)
@@ -258,3 +265,12 @@ func DetermineDaysLeft(fromDateLocal time.Time, toDateLocal time.Time) int {
 	toDate := now.With(toDateLocal).EndOfDay()
 	return int(math.Floor(toDate.Sub(fromDate).Hours() / 24))
 }
+
+func ValidateIPAddress(ipAddress string) (cleanedIPAddress string, err error) {
+	ipAddress = strings.ToLower(strings.TrimSpace(ipAddress))
+	ip := net.ParseIP(ipAddress)
+	if ip == nil {
+		return "", errors.Error("invalid IP address")
+	}
+	return ipAddress, nil
+}
diff --git a/utils/utils_test.go b/utils/utils_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..b1a07699ec800d5f43bea7aef7aef65d843a992d
--- /dev/null
+++ b/utils/utils_test.go
@@ -0,0 +1,148 @@
+package utils
+
+import (
+	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/errors"
+	"testing"
+)
+
+func TestStripEmail(t *testing.T) {
+	tests := []struct {
+		name         string
+		email        string
+		wantStripped string
+		wantDomain   string
+	}{
+		{
+			name:         "Test with + symbol",
+			email:        "test+extra@gmail.com",
+			wantStripped: "test@gmail.com",
+			wantDomain:   "gmail.com",
+		},
+		{
+			name:         "Test without + symbol",
+			email:        "test@gmail.com",
+			wantStripped: "test@gmail.com",
+			wantDomain:   "gmail.com",
+		},
+		{
+			name:         "Test with multiple + symbols",
+			email:        "test+extra+more@gmail.com",
+			wantStripped: "test@gmail.com",
+			wantDomain:   "gmail.com",
+		},
+		{
+			name:         "Test with different domain",
+			email:        "test+extra@yahoo.com",
+			wantStripped: "test@yahoo.com",
+			wantDomain:   "yahoo.com",
+		},
+		{
+			name:         "Test with subdomain",
+			email:        "test+extra@mail.example.com",
+			wantStripped: "test@mail.example.com",
+			wantDomain:   "mail.example.com",
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			gotStripped, gotDomain := StripEmail(tt.email)
+			if gotStripped != tt.wantStripped {
+				t.Errorf("StripEmail() gotStripped = %v, want %v", gotStripped, tt.wantStripped)
+			}
+			if gotDomain != tt.wantDomain {
+				t.Errorf("StripEmail() gotDomain = %v, want %v", gotDomain, tt.wantDomain)
+			}
+		})
+	}
+}
+
+func TestNormalizeEmail(t *testing.T) {
+	tests := []struct {
+		name           string
+		email          string
+		wantNormalized string
+	}{
+		{
+			name:           "Test with + symbol",
+			email:          "test+extra@gmail.com",
+			wantNormalized: "test@gmail.com",
+		},
+		{
+			name:           "Test without + symbol",
+			email:          "test@gmail.com",
+			wantNormalized: "test@gmail.com",
+		},
+		{
+			name:           "Test with multiple + symbols",
+			email:          "test+extra+more@gmail.com",
+			wantNormalized: "test@gmail.com",
+		},
+		{
+			name:           "Test with different domain",
+			email:          "test-extra@yahoo.com",
+			wantNormalized: "testextra@yahoo.com",
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			gotNormalized := NormalizeEmail(tt.email)
+			if gotNormalized != tt.wantNormalized {
+				t.Errorf("NormalizeEmail() gotNormalized = %v, want %v", gotNormalized, tt.wantNormalized)
+			}
+		})
+	}
+}
+
+func TestValidateIPAddress(t *testing.T) {
+	tests := []struct {
+		name string
+		ip   string
+		want string
+		err  error
+	}{
+		{
+			name: "Test with valid IPv4",
+			ip:   "192.168.1.1",
+			want: "192.168.1.1",
+			err:  nil,
+		},
+		{
+			name: "Test with valid IPv6",
+			ip:   "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
+			want: "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
+			err:  nil,
+		},
+		{
+			name: "Test with invalid IP",
+			ip:   "999.999.999.999",
+			want: "",
+			err:  errors.Error("invalid IP address"),
+		},
+		{
+			name: "Test with empty string",
+			ip:   "",
+			want: "",
+			err:  errors.Error("invalid IP address"),
+		},
+		{
+			name: "Test with non-IP string",
+			ip:   "not an ip address",
+			want: "",
+			err:  errors.Error("invalid IP address"),
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := ValidateIPAddress(tt.ip)
+			if got != tt.want {
+				t.Errorf("ValidateIPAddress() got = %v, want %v", got, tt.want)
+			}
+			if err != nil && err.Error() != tt.err.Error() {
+				t.Errorf("ValidateIPAddress() err = %v, want %v", err, tt.err)
+			}
+		})
+	}
+}