Repository: go-playground/validator
Pull request #1196 (2023-11-15 13:06:59)

MongoDB validator improved
## Enhances

Added MongoDB connection string validation


**Make sure that you've checked the boxes below before you submit PR:**
- [x] Tests exist or have been written that cover this particular change.

@go-playground/validator-maintainers

coveralls: 
[![Coverage Status](https://coveralls.io/builds/63973589/badge)](https://coveralls.io/builds/63973589)

coverage: 73.913% (+0.01%) from 73.903%
when pulling **13e57508d8821939cac146f56cbe8656caca9121 on pixel365:mongodb**
into **84254aeb5a59e615ec0b66ab53b988bc0677f55e on go-playground:master**.


Patch:
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index a5346d2..75cdc25 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -8,31 +8,23 @@ jobs:
   test:
     strategy:
       matrix:
-        go-version: [1.17.x,1.18.x,1.21.x]
+        go-version: [1.17.x,1.18.x,1.21.x,1.22.x]
         os: [ubuntu-latest, macos-latest, windows-latest]
     runs-on: ${{ matrix.os }}
     steps:
-      - name: Install Go
-        uses: actions/setup-go@v3
-        with:
-          go-version: ${{ matrix.go-version }}
-
       - name: Checkout code
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
-      - name: Restore Cache
-        uses: actions/cache@v3
+      - name: Install Go
+        uses: actions/setup-go@v5
         with:
-          path: ~/go/pkg/mod
-          key: ${{ runner.os }}-v1-go-${{ hashFiles('**/go.sum') }}
-          restore-keys: |
-            ${{ runner.os }}-v1-go-
+          go-version: ${{ matrix.go-version }}
 
       - name: Test
         run: go test -race -covermode=atomic -coverprofile="profile.cov" ./...
 
       - name: Send Coverage
-        if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.21.x'
+        if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.22.x'
         uses: shogo82148/actions-goveralls@v1
         with:
           path-to-profile: profile.cov
@@ -41,11 +33,11 @@ jobs:
     name: lint
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/setup-go@v3
+      - uses: actions/checkout@v4
+      - uses: actions/setup-go@v5
         with:
-          go-version: 1.21.x
-      - uses: actions/checkout@v3
+          go-version: 1.22.x
       - name: golangci-lint
-        uses: golangci/golangci-lint-action@v3
+        uses: golangci/golangci-lint-action@v4
         with:
           version: latest
diff --git a/Makefile b/Makefile
index 09f171b..e097dfa 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-GOCMD=GO111MODULE=on go
+GOCMD=go
 
 linters-install:
 	@golangci-lint --version >/dev/null 2>&1 || { \
@@ -15,4 +15,4 @@ test:
 bench:
 	$(GOCMD) test -run=NONE -bench=. -benchmem ./...
 
-.PHONY: test lint linters-install
\ No newline at end of file
+.PHONY: test lint linters-install
diff --git a/README.md b/README.md
index dbbafc3..e48cb8d 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 Package validator
 =================
 <img align="right" src="logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-![Project status](https://img.shields.io/badge/version-10.16.0-green.svg)
+![Project status](https://img.shields.io/badge/version-10.20.0-green.svg)
 [![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator)
 [![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
 [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
@@ -163,6 +163,7 @@ validate := validator.New(validator.WithRequiredStructEnabled())
 | btc_addr_bech32 | Bitcoin Bech32 Address (segwit) |
 | credit_card | Credit Card Number |
 | mongodb | MongoDB ObjectID |
+| mongodb_connection_string | MongoDB Connection String |
 | cron | Cron |
 | spicedb | SpiceDb ObjectID/Permission/Type |
 | datetime | Datetime |
diff --git a/baked_in.go b/baked_in.go
index 95f56e0..4e2cea6 100644
--- a/baked_in.go
+++ b/baked_in.go
@@ -64,8 +64,9 @@ var (
 	// defines a common or complex set of validation(s) to simplify
 	// adding validation to structs.
 	bakedInAliases = map[string]string{
-		"iscolor":      "hexcolor|rgb|rgba|hsl|hsla",
-		"country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
+		"iscolor":         "hexcolor|rgb|rgba|hsl|hsla",
+		"country_code":    "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
+		"eu_country_code": "iso3166_1_alpha2_eu|iso3166_1_alpha3_eu|iso3166_1_alpha_numeric_eu",
 	}
 
 	// bakedInValidators is the default map of ValidationFunc
@@ -133,6 +134,7 @@ var (
 		"urn_rfc2141":                   isUrnRFC2141, // RFC 2141
 		"file":                          isFile,
 		"filepath":                      isFilePath,
+		"base32":                        isBase32,
 		"base64":                        isBase64,
 		"base64url":                     isBase64URL,
 		"base64rawurl":                  isBase64RawURL,
@@ -216,8 +218,11 @@ var (
 		"datetime":                      isDatetime,
 		"timezone":                      isTimeZone,
 		"iso3166_1_alpha2":              isIso3166Alpha2,
+		"iso3166_1_alpha2_eu":           isIso3166Alpha2EU,
 		"iso3166_1_alpha3":              isIso3166Alpha3,
+		"iso3166_1_alpha3_eu":           isIso3166Alpha3EU,
 		"iso3166_1_alpha_numeric":       isIso3166AlphaNumeric,
+		"iso3166_1_alpha_numeric_eu":    isIso3166AlphaNumericEU,
 		"iso3166_2":                     isIso31662,
 		"iso4217":                       isIso4217,
 		"iso4217_numeric":               isIso4217Numeric,
@@ -230,7 +235,8 @@ var (
 		"credit_card":                   isCreditCard,
 		"cve":                           isCveFormat,
 		"luhn_checksum":                 hasLuhnChecksum,
-		"mongodb":                       isMongoDB,
+		"mongodb":                       isMongoDBObjectId,
+		"mongodb_connection_string":     isMongoDBConnectionString,
 		"cron":                          isCron,
 		"spicedb":                       isSpiceDB,
 	}
@@ -1399,6 +1405,11 @@ func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool {
 	return reg.MatchString(field.String())
 }
 
+// isBase32 is the validation function for validating if the current field's value is a valid base 32.
+func isBase32(fl FieldLevel) bool {
+	return base32Regex.MatchString(fl.Field().String())
+}
+
 // isBase64 is the validation function for validating if the current field's value is a valid base 64.
 func isBase64(fl FieldLevel) bool {
 	return base64Regex.MatchString(fl.Field().String())
@@ -2762,12 +2773,24 @@ func isIso3166Alpha2(fl FieldLevel) bool {
 	return iso3166_1_alpha2[val]
 }
 
+// isIso3166Alpha2EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-2 European Union country code.
+func isIso3166Alpha2EU(fl FieldLevel) bool {
+	val := fl.Field().String()
+	return iso3166_1_alpha2_eu[val]
+}
+
 // isIso3166Alpha3 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 country code.
 func isIso3166Alpha3(fl FieldLevel) bool {
 	val := fl.Field().String()
 	return iso3166_1_alpha3[val]
 }
 
+// isIso3166Alpha3EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 European Union country code.
+func isIso3166Alpha3EU(fl FieldLevel) bool {
+	val := fl.Field().String()
+	return iso3166_1_alpha3_eu[val]
+}
+
 // isIso3166AlphaNumeric is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric country code.
 func isIso3166AlphaNumeric(fl FieldLevel) bool {
 	field := fl.Field()
@@ -2790,6 +2813,28 @@ func isIso3166AlphaNumeric(fl FieldLevel) bool {
 	return iso3166_1_alpha_numeric[code]
 }
 
+// isIso3166AlphaNumericEU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric European Union country code.
+func isIso3166AlphaNumericEU(fl FieldLevel) bool {
+	field := fl.Field()
+
+	var code int
+	switch field.Kind() {
+	case reflect.String:
+		i, err := strconv.Atoi(field.String())
+		if err != nil {
+			return false
+		}
+		code = i % 1000
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		code = int(field.Int() % 1000)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		code = int(field.Uint() % 1000)
+	default:
+		panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+	}
+	return iso3166_1_alpha_numeric_eu[code]
+}
+
 // isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code.
 func isIso31662(fl FieldLevel) bool {
 	val := fl.Field().String()
@@ -2882,10 +2927,16 @@ func digitsHaveLuhnChecksum(digits []string) bool {
 	return (sum % 10) == 0
 }
 
-// isMongoDB is the validation function for validating if the current field's value is valid mongoDB objectID
-func isMongoDB(fl FieldLevel) bool {
+// isMongoDBObjectId is the validation function for validating if the current field's value is valid MongoDB ObjectID
+func isMongoDBObjectId(fl FieldLevel) bool {
+	val := fl.Field().String()
+	return mongodbIdRegex.MatchString(val)
+}
+
+// isMongoDBConnectionString is the validation function for validating if the current field's value is valid MongoDB Connection String
+func isMongoDBConnectionString(fl FieldLevel) bool {
 	val := fl.Field().String()
-	return mongodbRegex.MatchString(val)
+	return mongodbConnectionRegex.MatchString(val)
 }
 
 // isSpiceDB is the validation function for validating if the current field's value is valid for use with Authzed SpiceDB in the indicated way
diff --git a/cache.go b/cache.go
index 0f4fa6b..b6bdd11 100644
--- a/cache.go
+++ b/cache.go
@@ -126,7 +126,7 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr
 
 		fld = typ.Field(i)
 
-		if !fld.Anonymous && len(fld.PkgPath) > 0 {
+		if !v.privateFieldValidation && !fld.Anonymous && len(fld.PkgPath) > 0 {
 			continue
 		}
 
diff --git a/country_codes.go b/country_codes.go
index 0119f05..e507149 100644
--- a/country_codes.go
+++ b/country_codes.go
@@ -54,6 +54,15 @@ var iso3166_1_alpha2 = map[string]bool{
 	"EH": true, "YE": true, "ZM": true, "ZW": true, "XK": true,
 }
 
+var iso3166_1_alpha2_eu = map[string]bool{
+	"AT": true, "BE": true, "BG": true, "HR": true, "CY": true,
+	"CZ": true, "DK": true, "EE": true, "FI": true, "FR": true,
+	"DE": true, "GR": true, "HU": true, "IE": true, "IT": true,
+	"LV": true, "LT": true, "LU": true, "MT": true, "NL": true,
+	"PL": true, "PT": true, "RO": true, "SK": true, "SI": true,
+	"ES": true, "SE": true,
+}
+
 var iso3166_1_alpha3 = map[string]bool{
 	// see: https://www.iso.org/iso-3166-country-codes.html
 	"AFG": true, "ALB": true, "DZA": true, "ASM": true, "AND": true,
@@ -107,6 +116,15 @@ var iso3166_1_alpha3 = map[string]bool{
 	"VNM": true, "VGB": true, "VIR": true, "WLF": true, "ESH": true,
 	"YEM": true, "ZMB": true, "ZWE": true, "ALA": true, "UNK": true,
 }
+
+var iso3166_1_alpha3_eu = map[string]bool{
+	"AUT": true, "BEL": true, "BGR": true, "HRV": true, "CYP": true,
+	"CZE": true, "DNK": true, "EST": true, "FIN": true, "FRA": true,
+	"DEU": true, "GRC": true, "HUN": true, "IRL": true, "ITA": true,
+	"LVA": true, "LTU": true, "LUX": true, "MLT": true, "NLD": true,
+	"POL": true, "PRT": true, "ROU": true, "SVK": true, "SVN": true,
+	"ESP": true, "SWE": true,
+}
 var iso3166_1_alpha_numeric = map[int]bool{
 	// see: https://www.iso.org/iso-3166-country-codes.html
 	4: true, 8: true, 12: true, 16: true, 20: true,
@@ -161,6 +179,15 @@ var iso3166_1_alpha_numeric = map[int]bool{
 	887: true, 894: true, 716: true, 248: true, 153: true,
 }
 
+var iso3166_1_alpha_numeric_eu = map[int]bool{
+	40: true, 56: true, 100: true, 191: true, 196: true,
+	200: true, 208: true, 233: true, 246: true, 250: true,
+	276: true, 300: true, 348: true, 372: true, 380: true,
+	428: true, 440: true, 442: true, 470: true, 528: true,
+	616: true, 620: true, 642: true, 703: true, 705: true,
+	724: true, 752: true,
+}
+
 var iso3166_2 = map[string]bool{
 	"AD-02": true, "AD-03": true, "AD-04": true, "AD-05": true, "AD-06": true,
 	"AD-07": true, "AD-08": true, "AE-AJ": true, "AE-AZ": true, "AE-DU": true,
diff --git a/doc.go b/doc.go
index b474091..546f95a 100644
--- a/doc.go
+++ b/doc.go
@@ -916,6 +916,15 @@ according to the RFC 2141 spec.
 
 	Usage: urn_rfc2141
 
+# Base32 String
+
+This validates that a string value contains a valid bas324 value.
+Although an empty string is valid base32 this will report an empty string
+as an error, if you wish to accept an empty string as valid you can use
+this with the omitempty tag.
+
+	Usage: base32
+
 # Base64 String
 
 This validates that a string value contains a valid base64 value.
@@ -1377,11 +1386,19 @@ This validates that a string value contains a valid credit card number using Luh
 
 This validates that a string or (u)int value contains a valid checksum using the Luhn algorithm.
 
-# MongoDb ObjectID
+# MongoDB
 
-This validates that a string is a valid 24 character hexadecimal string.
+This validates that a string is a valid 24 character hexadecimal string or valid connection string.
 
 	Usage: mongodb
+	       mongodb_connection_string
+
+Example:
+
+	type Test struct {
+		ObjectIdField         string `validate:"mongodb"`
+		ConnectionStringField string `validate:"mongodb_connection_string"`
+	}
 
 # Cron
 
diff --git a/errors.go b/errors.go
index 5856d57..be2676e 100644
--- a/errors.go
+++ b/errors.go
@@ -257,15 +257,19 @@ func (fe *fieldError) Error() string {
 // NOTE: if no registered translation can be found, it returns the original
 // untranslated error message.
 func (fe *fieldError) Translate(ut ut.Translator) string {
+	var fn TranslationFunc
 
 	m, ok := fe.v.transTagFunc[ut]
 	if !ok {
 		return fe.Error()
 	}
 
-	fn, ok := m[fe.tag]
+	fn, ok = m[fe.tag]
 	if !ok {
-		return fe.Error()
+		fn, ok = m[fe.actualTag]
+		if !ok {
+			return fe.Error()
+		}
 	}
 
 	return fn(ut, fe)
diff --git a/go.mod b/go.mod
index 3e03df2..c77643f 100644
--- a/go.mod
+++ b/go.mod
@@ -3,16 +3,16 @@ module github.com/go-playground/validator/v10
 go 1.18
 
 require (
-	github.com/gabriel-vasile/mimetype v1.4.2
+	github.com/gabriel-vasile/mimetype v1.4.3
 	github.com/go-playground/assert/v2 v2.2.0
 	github.com/go-playground/locales v0.14.1
 	github.com/go-playground/universal-translator v0.18.1
-	github.com/leodido/go-urn v1.2.4
-	golang.org/x/crypto v0.7.0
-	golang.org/x/text v0.8.0
+	github.com/leodido/go-urn v1.4.0
+	golang.org/x/crypto v0.19.0
+	golang.org/x/text v0.14.0
 )
 
 require (
-	golang.org/x/net v0.8.0 // indirect
-	golang.org/x/sys v0.6.0 // indirect
+	golang.org/x/net v0.21.0 // indirect
+	golang.org/x/sys v0.17.0 // indirect
 )
diff --git a/go.sum b/go.sum
index b4e2760..3bf8a6e 100644
--- a/go.sum
+++ b/go.sum
@@ -1,34 +1,22 @@
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 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/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
-github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
+github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
 github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
 github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
 github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
 github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
 github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
 github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
-github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
-github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
-github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
-github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
-golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
-golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/options.go b/options.go
index 1dea56f..86a0db2 100644
--- a/options.go
+++ b/options.go
@@ -14,3 +14,13 @@ func WithRequiredStructEnabled() Option {
 		v.requiredStructEnabled = true
 	}
 }
+
+// WithPrivateFieldValidation activates validation for unexported fields via the use of the `unsafe` package.
+//
+// By opting into this feature you are acknowledging that you are aware of the risks and accept any current or future
+// consequences of using this feature.
+func WithPrivateFieldValidation() Option {
+	return func(v *Validate) {
+		v.privateFieldValidation = true
+	}
+}
diff --git a/regexes.go b/regexes.go
index af98d8d..5620fd7 100644
--- a/regexes.go
+++ b/regexes.go
@@ -17,6 +17,7 @@ const (
 	hslaRegexString                  = "^hsla\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
 	emailRegexString                 = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
 	e164RegexString                  = "^\\+[1-9]?[0-9]{7,14}$"
+	base32RegexString                = "^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=|[A-Z2-7]{8})$"
 	base64RegexString                = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
 	base64URLRegexString             = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2}==|[A-Za-z0-9-_]{3}=|[A-Za-z0-9-_]{4})$"
 	base64RawURLRegexString          = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2,4})$"
@@ -31,7 +32,7 @@ const (
 	uUID4RFC4122RegexString          = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
 	uUID5RFC4122RegexString          = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
 	uUIDRFC4122RegexString           = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
-	uLIDRegexString                  = "^[A-HJKMNP-TV-Z0-9]{26}$"
+	uLIDRegexString                  = "^(?i)[A-HJKMNP-TV-Z0-9]{26}$"
 	md4RegexString                   = "^[0-9a-f]{32}$"
 	md5RegexString                   = "^[0-9a-f]{32}$"
 	sha256RegexString                = "^[0-9a-f]{64}$"
@@ -67,7 +68,8 @@ const (
 	semverRegexString                = `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` // numbered capture groups https://semver.org/
 	dnsRegexStringRFC1035Label       = "^[a-z]([-a-z0-9]*[a-z0-9]){0,62}$"
 	cveRegexString                   = `^CVE-(1999|2\d{3})-(0[^0]\d{2}|0\d[^0]\d{1}|0\d{2}[^0]|[1-9]{1}\d{3,})$` // CVE Format Id https://cve.mitre.org/cve/identifiers/syntaxchange.html
-	mongodbRegexString               = "^[a-f\\d]{24}$"
+	mongodbIdRegexString             = "^[a-f\\d]{24}$"
+	mongodbConnStringRegexString     = "^mongodb(\\+srv)?:\\/\\/(([a-zA-Z\\d]+):([a-zA-Z\\d$:\\/?#\\[\\]@]+)@)?(([a-z\\d.-]+)(:[\\d]+)?)((,(([a-z\\d.-]+)(:(\\d+))?))*)?(\\/[a-zA-Z-_]{1,64})?(\\?(([a-zA-Z]+)=([a-zA-Z\\d]+))(&(([a-zA-Z\\d]+)=([a-zA-Z\\d]+))?)*)?$"
 	cronRegexString                  = `(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7})`
 	spicedbIDRegexString             = `^(([a-zA-Z0-9/_|\-=+]{1,})|\*)$`
 	spicedbPermissionRegexString     = "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
@@ -89,6 +91,7 @@ var (
 	hslaRegex                  = regexp.MustCompile(hslaRegexString)
 	e164Regex                  = regexp.MustCompile(e164RegexString)
 	emailRegex                 = regexp.MustCompile(emailRegexString)
+	base32Regex                = regexp.MustCompile(base32RegexString)
 	base64Regex                = regexp.MustCompile(base64RegexString)
 	base64URLRegex             = regexp.MustCompile(base64URLRegexString)
 	base64RawURLRegex          = regexp.MustCompile(base64RawURLRegexString)
@@ -137,7 +140,8 @@ var (
 	semverRegex                = regexp.MustCompile(semverRegexString)
 	dnsRegexRFC1035Label       = regexp.MustCompile(dnsRegexStringRFC1035Label)
 	cveRegex                   = regexp.MustCompile(cveRegexString)
-	mongodbRegex               = regexp.MustCompile(mongodbRegexString)
+	mongodbIdRegex             = regexp.MustCompile(mongodbIdRegexString)
+	mongodbConnectionRegex     = regexp.MustCompile(mongodbConnStringRegexString)
 	cronRegex                  = regexp.MustCompile(cronRegexString)
 	spicedbIDRegex             = regexp.MustCompile(spicedbIDRegexString)
 	spicedbPermissionRegex     = regexp.MustCompile(spicedbPermissionRegexString)
diff --git a/translations/en/en.go b/translations/en/en.go
index 4c34ded..9cef10e 100644
--- a/translations/en/en.go
+++ b/translations/en/en.go
@@ -34,6 +34,66 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
 			translation: "{0} is a required field",
 			override:    false,
 		},
+		{
+			tag:         "required_unless",
+			translation: "{0} is a required field",
+			override:    false,
+		},
+		{
+			tag:         "required_with",
+			translation: "{0} is a required field",
+			override:    false,
+		},
+		{
+			tag:         "required_with_all",
+			translation: "{0} is a required field",
+			override:    false,
+		},
+		{
+			tag:         "required_without",
+			translation: "{0} is a required field",
+			override:    false,
+		},
+		{
+			tag:         "required_without_all",
+			translation: "{0} is a required field",
+			override:    false,
+		},
+		{
+			tag:         "excluded_if",
+			translation: "{0} is an excluded field",
+			override:    false,
+		},
+		{
+			tag:         "excluded_unless",
+			translation: "{0} is an excluded field",
+			override:    false,
+		},
+		{
+			tag:         "excluded_with",
+			translation: "{0} is an excluded field",
+			override:    false,
+		},
+		{
+			tag:         "excluded_with_all",
+			translation: "{0} is an excluded field",
+			override:    false,
+		},
+		{
+			tag:         "excluded_without",
+			translation: "{0} is an excluded field",
+			override:    false,
+		},
+		{
+			tag:         "excluded_without_all",
+			translation: "{0} is an excluded field",
+			override:    false,
+		},
+		{
+			tag:         "isdefault",
+			translation: "{0} must be default value",
+			override:    false,
+		},
 		{
 			tag: "len",
 			customRegisFunc: func(ut ut.Translator) (err error) {
diff --git a/translations/zh/zh.go b/translations/zh/zh.go
index 0b084e5..19221e3 100644
--- a/translations/zh/zh.go
+++ b/translations/zh/zh.go
@@ -59,6 +59,41 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
 			translation: "{0}为必填字段",
 			override:    false,
 		},
+		{
+			tag:         "excluded_if",
+			translation: "{0}为禁填字段",
+			override:    false,
+		},
+		{
+			tag:         "excluded_unless",
+			translation: "{0}为禁填字段",
+			override:    false,
+		},
+		{
+			tag:         "excluded_with",
+			translation: "{0}为禁填字段",
+			override:    false,
+		},
+		{
+			tag:         "excluded_with_all",
+			translation: "{0}为禁填字段",
+			override:    false,
+		},
+		{
+			tag:         "excluded_without",
+			translation: "{0}为禁填字段",
+			override:    false,
+		},
+		{
+			tag:         "excluded_without_all",
+			translation: "{0}为禁填字段",
+			override:    false,
+		},
+		{
+			tag:         "isdefault",
+			translation: "{0}为禁填字段",
+			override:    false,
+		},
 		{
 			tag: "len",
 			customRegisFunc: func(ut ut.Translator) (err error) {
diff --git a/translations/zh_tw/zh_tw.go b/translations/zh_tw/zh_tw.go
index e465eb6..a11bdc8 100644
--- a/translations/zh_tw/zh_tw.go
+++ b/translations/zh_tw/zh_tw.go
@@ -29,6 +29,71 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
 			translation: "{0}為必填欄位",
 			override:    false,
 		},
+		{
+			tag:         "required_if",
+			translation: "{0}為必填欄位",
+			override:    false,
+		},
+		{
+			tag:         "required_unless",
+			translation: "{0}為必填欄位",
+			override:    false,
+		},
+		{
+			tag:         "required_with",
+			translation: "{0}為必填欄位",
+			override:    false,
+		},
+		{
+			tag:         "required_with_all",
+			translation: "{0}為必填欄位",
+			override:    false,
+		},
+		{
+			tag:         "required_without",
+			translation: "{0}為必填欄位",
+			override:    false,
+		},
+		{
+			tag:         "required_without_all",
+			translation: "{0}為必填欄位",
+			override:    false,
+		},
+		{
+			tag:         "excluded_if",
+			translation: "{0}為禁填欄位",
+			override:    false,
+		},
+		{
+			tag:         "excluded_unless",
+			translation: "{0}為禁填欄位",
+			override:    false,
+		},
+		{
+			tag:         "excluded_with",
+			translation: "{0}為禁填欄位",
+			override:    false,
+		},
+		{
+			tag:         "excluded_with_all",
+			translation: "{0}為禁填欄位",
+			override:    false,
+		},
+		{
+			tag:         "excluded_without",
+			translation: "{0}為禁填欄位",
+			override:    false,
+		},
+		{
+			tag:         "excluded_without_all",
+			translation: "{0}為禁填欄位",
+			override:    false,
+		},
+		{
+			tag:         "isdefault",
+			translation: "{0}為禁填欄位",
+			override:    false,
+		},
 		{
 			tag: "len",
 			customRegisFunc: func(ut ut.Translator) (err error) {
diff --git a/validator.go b/validator.go
index a072d39..901e7b5 100644
--- a/validator.go
+++ b/validator.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"reflect"
 	"strconv"
+	"unsafe"
 )
 
 // per validate construct
@@ -156,7 +157,7 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
 						structNs:       v.str2,
 						fieldLen:       uint8(len(cf.altName)),
 						structfieldLen: uint8(len(cf.name)),
-						value:          current.Interface(),
+						value:          getValue(current),
 						param:          ct.param,
 						kind:           kind,
 						typ:            current.Type(),
@@ -410,7 +411,7 @@ OUTER:
 								structNs:       v.str2,
 								fieldLen:       uint8(len(cf.altName)),
 								structfieldLen: uint8(len(cf.name)),
-								value:          current.Interface(),
+								value:          getValue(current),
 								param:          ct.param,
 								kind:           kind,
 								typ:            typ,
@@ -430,7 +431,7 @@ OUTER:
 								structNs:       v.str2,
 								fieldLen:       uint8(len(cf.altName)),
 								structfieldLen: uint8(len(cf.name)),
-								value:          current.Interface(),
+								value:          getValue(current),
 								param:          ct.param,
 								kind:           kind,
 								typ:            typ,
@@ -470,7 +471,7 @@ OUTER:
 						structNs:       v.str2,
 						fieldLen:       uint8(len(cf.altName)),
 						structfieldLen: uint8(len(cf.name)),
-						value:          current.Interface(),
+						value:          getValue(current),
 						param:          ct.param,
 						kind:           kind,
 						typ:            typ,
@@ -484,3 +485,26 @@ OUTER:
 	}
 
 }
+
+func getValue(val reflect.Value) interface{} {
+	if val.CanInterface() {
+		return val.Interface()
+	}
+
+	if val.CanAddr() {
+		return reflect.NewAt(val.Type(), unsafe.Pointer(val.UnsafeAddr())).Elem().Interface()
+	}
+
+	switch val.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return val.Int()
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return val.Uint()
+	case reflect.Complex64, reflect.Complex128:
+		return val.Complex()
+	case reflect.Float32, reflect.Float64:
+		return val.Float()
+	default:
+		return val.String()
+	}
+}
diff --git a/validator_instance.go b/validator_instance.go
index d5a7be1..1a34513 100644
--- a/validator_instance.go
+++ b/validator_instance.go
@@ -80,20 +80,21 @@ type internalValidationFuncWrapper struct {
 
 // Validate contains the validator settings and cache
 type Validate struct {
-	tagName               string
-	pool                  *sync.Pool
-	tagNameFunc           TagNameFunc
-	structLevelFuncs      map[reflect.Type]StructLevelFuncCtx
-	customFuncs           map[reflect.Type]CustomTypeFunc
-	aliases               map[string]string
-	validations           map[string]internalValidationFuncWrapper
-	transTagFunc          map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc
-	rules                 map[reflect.Type]map[string]string
-	tagCache              *tagCache
-	structCache           *structCache
-	hasCustomFuncs        bool
-	hasTagNameFunc        bool
-	requiredStructEnabled bool
+	tagName                string
+	pool                   *sync.Pool
+	tagNameFunc            TagNameFunc
+	structLevelFuncs       map[reflect.Type]StructLevelFuncCtx
+	customFuncs            map[reflect.Type]CustomTypeFunc
+	aliases                map[string]string
+	validations            map[string]internalValidationFuncWrapper
+	transTagFunc           map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc
+	rules                  map[reflect.Type]map[string]string
+	tagCache               *tagCache
+	structCache            *structCache
+	hasCustomFuncs         bool
+	hasTagNameFunc         bool
+	requiredStructEnabled  bool
+	privateFieldValidation bool
 }
 
 // New returns a new instance of 'validate' with sane defaults.


Test patch:
diff --git a/translations/en/en_test.go b/translations/en/en_test.go
index 6782f3b..e5d397e 100644
--- a/translations/en/en_test.go
+++ b/translations/en/en_test.go
@@ -21,141 +21,164 @@ func TestTranslations(t *testing.T) {
 	Equal(t, err, nil)
 
 	type Inner struct {
-		EqCSFieldString  string
-		NeCSFieldString  string
-		GtCSFieldString  string
-		GteCSFieldString string
-		LtCSFieldString  string
-		LteCSFieldString string
-		RequiredIf       string
+		EqCSFieldString    string
+		NeCSFieldString    string
+		GtCSFieldString    string
+		GteCSFieldString   string
+		LtCSFieldString    string
+		LteCSFieldString   string
+		RequiredIf         string
+		RequiredUnless     string
+		RequiredWith       string
+		RequiredWithAll    string
+		RequiredWithout    string
+		RequiredWithoutAll string
+		ExcludedIf         string
+		ExcludedUnless     string
+		ExcludedWith       string
+		ExcludedWithAll    string
+		ExcludedWithout    string
+		ExcludedWithoutAll string
 	}
 
 	type Test struct {
-		Inner             Inner
-		RequiredString    string            `validate:"required"`
-		RequiredNumber    int               `validate:"required"`
-		RequiredMultiple  []string          `validate:"required"`
-		RequiredIf        string            `validate:"required_if=Inner.RequiredIf abcd"`
-		LenString         string            `validate:"len=1"`
-		LenNumber         float64           `validate:"len=1113.00"`
-		LenMultiple       []string          `validate:"len=7"`
-		MinString         string            `validate:"min=1"`
-		MinNumber         float64           `validate:"min=1113.00"`
-		MinMultiple       []string          `validate:"min=7"`
-		MaxString         string            `validate:"max=3"`
-		MaxNumber         float64           `validate:"max=1113.00"`
-		MaxMultiple       []string          `validate:"max=7"`
-		EqString          string            `validate:"eq=3"`
-		EqNumber          float64           `validate:"eq=2.33"`
-		EqMultiple        []string          `validate:"eq=7"`
-		NeString          string            `validate:"ne="`
-		NeNumber          float64           `validate:"ne=0.00"`
-		NeMultiple        []string          `validate:"ne=0"`
-		LtString          string            `validate:"lt=3"`
-		LtNumber          float64           `validate:"lt=5.56"`
-		LtMultiple        []string          `validate:"lt=2"`
-		LtTime            time.Time         `validate:"lt"`
-		LteString         string            `validate:"lte=3"`
-		LteNumber         float64           `validate:"lte=5.56"`
-		LteMultiple       []string          `validate:"lte=2"`
-		LteTime           time.Time         `validate:"lte"`
-		GtString          string            `validate:"gt=3"`
-		GtNumber          float64           `validate:"gt=5.56"`
-		GtMultiple        []string          `validate:"gt=2"`
-		GtTime            time.Time         `validate:"gt"`
-		GteString         string            `validate:"gte=3"`
-		GteNumber         float64           `validate:"gte=5.56"`
-		GteMultiple       []string          `validate:"gte=2"`
-		GteTime           time.Time         `validate:"gte"`
-		EqFieldString     string            `validate:"eqfield=MaxString"`
-		EqCSFieldString   string            `validate:"eqcsfield=Inner.EqCSFieldString"`
-		NeCSFieldString   string            `validate:"necsfield=Inner.NeCSFieldString"`
-		GtCSFieldString   string            `validate:"gtcsfield=Inner.GtCSFieldString"`
-		GteCSFieldString  string            `validate:"gtecsfield=Inner.GteCSFieldString"`
-		LtCSFieldString   string            `validate:"ltcsfield=Inner.LtCSFieldString"`
-		LteCSFieldString  string            `validate:"ltecsfield=Inner.LteCSFieldString"`
-		NeFieldString     string            `validate:"nefield=EqFieldString"`
-		GtFieldString     string            `validate:"gtfield=MaxString"`
-		GteFieldString    string            `validate:"gtefield=MaxString"`
-		LtFieldString     string            `validate:"ltfield=MaxString"`
-		LteFieldString    string            `validate:"ltefield=MaxString"`
-		AlphaString       string            `validate:"alpha"`
-		AlphanumString    string            `validate:"alphanum"`
-		NumericString     string            `validate:"numeric"`
-		NumberString      string            `validate:"number"`
-		HexadecimalString string            `validate:"hexadecimal"`
-		HexColorString    string            `validate:"hexcolor"`
-		RGBColorString    string            `validate:"rgb"`
-		RGBAColorString   string            `validate:"rgba"`
-		HSLColorString    string            `validate:"hsl"`
-		HSLAColorString   string            `validate:"hsla"`
-		Email             string            `validate:"email"`
-		URL               string            `validate:"url"`
-		URI               string            `validate:"uri"`
-		Base64            string            `validate:"base64"`
-		Contains          string            `validate:"contains=purpose"`
-		ContainsAny       string            `validate:"containsany=!@#$"`
-		Excludes          string            `validate:"excludes=text"`
-		ExcludesAll       string            `validate:"excludesall=!@#$"`
-		ExcludesRune      string            `validate:"excludesrune=☻"`
-		ISBN              string            `validate:"isbn"`
-		ISBN10            string            `validate:"isbn10"`
-		ISBN13            string            `validate:"isbn13"`
-		ISSN              string            `validate:"issn"`
-		UUID              string            `validate:"uuid"`
-		UUID3             string            `validate:"uuid3"`
-		UUID4             string            `validate:"uuid4"`
-		UUID5             string            `validate:"uuid5"`
-		ULID              string            `validate:"ulid"`
-		ASCII             string            `validate:"ascii"`
-		PrintableASCII    string            `validate:"printascii"`
-		MultiByte         string            `validate:"multibyte"`
-		DataURI           string            `validate:"datauri"`
-		Latitude          string            `validate:"latitude"`
-		Longitude         string            `validate:"longitude"`
-		SSN               string            `validate:"ssn"`
-		IP                string            `validate:"ip"`
-		IPv4              string            `validate:"ipv4"`
-		IPv6              string            `validate:"ipv6"`
-		CIDR              string            `validate:"cidr"`
-		CIDRv4            string            `validate:"cidrv4"`
-		CIDRv6            string            `validate:"cidrv6"`
-		TCPAddr           string            `validate:"tcp_addr"`
-		TCPAddrv4         string            `validate:"tcp4_addr"`
-		TCPAddrv6         string            `validate:"tcp6_addr"`
-		UDPAddr           string            `validate:"udp_addr"`
-		UDPAddrv4         string            `validate:"udp4_addr"`
-		UDPAddrv6         string            `validate:"udp6_addr"`
-		IPAddr            string            `validate:"ip_addr"`
-		IPAddrv4          string            `validate:"ip4_addr"`
-		IPAddrv6          string            `validate:"ip6_addr"`
-		UinxAddr          string            `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
-		MAC               string            `validate:"mac"`
-		FQDN              string            `validate:"fqdn"`
-		IsColor           string            `validate:"iscolor"`
-		StrPtrMinLen      *string           `validate:"min=10"`
-		StrPtrMaxLen      *string           `validate:"max=1"`
-		StrPtrLen         *string           `validate:"len=2"`
-		StrPtrLt          *string           `validate:"lt=1"`
-		StrPtrLte         *string           `validate:"lte=1"`
-		StrPtrGt          *string           `validate:"gt=10"`
-		StrPtrGte         *string           `validate:"gte=10"`
-		OneOfString       string            `validate:"oneof=red green"`
-		OneOfInt          int               `validate:"oneof=5 63"`
-		UniqueSlice       []string          `validate:"unique"`
-		UniqueArray       [3]string         `validate:"unique"`
-		UniqueMap         map[string]string `validate:"unique"`
-		JSONString        string            `validate:"json"`
-		JWTString         string            `validate:"jwt"`
-		LowercaseString   string            `validate:"lowercase"`
-		UppercaseString   string            `validate:"uppercase"`
-		Datetime          string            `validate:"datetime=2006-01-02"`
-		PostCode          string            `validate:"postcode_iso3166_alpha2=SG"`
-		PostCodeCountry   string
-		PostCodeByField   string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
-		BooleanString     string `validate:"boolean"`
-		Image             string `validate:"image"`
-		CveString         string `validate:"cve"`
+		Inner              Inner
+		RequiredString     string            `validate:"required"`
+		RequiredNumber     int               `validate:"required"`
+		RequiredMultiple   []string          `validate:"required"`
+		RequiredIf         string            `validate:"required_if=Inner.RequiredIf abcd"`
+		RequiredUnless     string            `validate:"required_unless=Inner.RequiredUnless abcd"`
+		RequiredWith       string            `validate:"required_with=Inner.RequiredWith"`
+		RequiredWithAll    string            `validate:"required_with_all=Inner.RequiredWith Inner.RequiredWithAll"`
+		RequiredWithout    string            `validate:"required_without=Inner.RequiredWithout"`
+		RequiredWithoutAll string            `validate:"required_without_all=Inner.RequiredWithout Inner.RequiredWithoutAll"`
+		ExcludedIf         string            `validate:"excluded_if=Inner.ExcludedIf abcd"`
+		ExcludedUnless     string            `validate:"excluded_unless=Inner.ExcludedUnless abcd"`
+		ExcludedWith       string            `validate:"excluded_with=Inner.ExcludedWith"`
+		ExcludedWithout    string            `validate:"excluded_with_all=Inner.ExcludedWithAll"`
+		ExcludedWithAll    string            `validate:"excluded_without=Inner.ExcludedWithout"`
+		ExcludedWithoutAll string            `validate:"excluded_without_all=Inner.ExcludedWithoutAll"`
+		IsDefault          string            `validate:"isdefault"`
+		LenString          string            `validate:"len=1"`
+		LenNumber          float64           `validate:"len=1113.00"`
+		LenMultiple        []string          `validate:"len=7"`
+		MinString          string            `validate:"min=1"`
+		MinNumber          float64           `validate:"min=1113.00"`
+		MinMultiple        []string          `validate:"min=7"`
+		MaxString          string            `validate:"max=3"`
+		MaxNumber          float64           `validate:"max=1113.00"`
+		MaxMultiple        []string          `validate:"max=7"`
+		EqString           string            `validate:"eq=3"`
+		EqNumber           float64           `validate:"eq=2.33"`
+		EqMultiple         []string          `validate:"eq=7"`
+		NeString           string            `validate:"ne="`
+		NeNumber           float64           `validate:"ne=0.00"`
+		NeMultiple         []string          `validate:"ne=0"`
+		LtString           string            `validate:"lt=3"`
+		LtNumber           float64           `validate:"lt=5.56"`
+		LtMultiple         []string          `validate:"lt=2"`
+		LtTime             time.Time         `validate:"lt"`
+		LteString          string            `validate:"lte=3"`
+		LteNumber          float64           `validate:"lte=5.56"`
+		LteMultiple        []string          `validate:"lte=2"`
+		LteTime            time.Time         `validate:"lte"`
+		GtString           string            `validate:"gt=3"`
+		GtNumber           float64           `validate:"gt=5.56"`
+		GtMultiple         []string          `validate:"gt=2"`
+		GtTime             time.Time         `validate:"gt"`
+		GteString          string            `validate:"gte=3"`
+		GteNumber          float64           `validate:"gte=5.56"`
+		GteMultiple        []string          `validate:"gte=2"`
+		GteTime            time.Time         `validate:"gte"`
+		EqFieldString      string            `validate:"eqfield=MaxString"`
+		EqCSFieldString    string            `validate:"eqcsfield=Inner.EqCSFieldString"`
+		NeCSFieldString    string            `validate:"necsfield=Inner.NeCSFieldString"`
+		GtCSFieldString    string            `validate:"gtcsfield=Inner.GtCSFieldString"`
+		GteCSFieldString   string            `validate:"gtecsfield=Inner.GteCSFieldString"`
+		LtCSFieldString    string            `validate:"ltcsfield=Inner.LtCSFieldString"`
+		LteCSFieldString   string            `validate:"ltecsfield=Inner.LteCSFieldString"`
+		NeFieldString      string            `validate:"nefield=EqFieldString"`
+		GtFieldString      string            `validate:"gtfield=MaxString"`
+		GteFieldString     string            `validate:"gtefield=MaxString"`
+		LtFieldString      string            `validate:"ltfield=MaxString"`
+		LteFieldString     string            `validate:"ltefield=MaxString"`
+		AlphaString        string            `validate:"alpha"`
+		AlphanumString     string            `validate:"alphanum"`
+		NumericString      string            `validate:"numeric"`
+		NumberString       string            `validate:"number"`
+		HexadecimalString  string            `validate:"hexadecimal"`
+		HexColorString     string            `validate:"hexcolor"`
+		RGBColorString     string            `validate:"rgb"`
+		RGBAColorString    string            `validate:"rgba"`
+		HSLColorString     string            `validate:"hsl"`
+		HSLAColorString    string            `validate:"hsla"`
+		Email              string            `validate:"email"`
+		URL                string            `validate:"url"`
+		URI                string            `validate:"uri"`
+		Base64             string            `validate:"base64"`
+		Contains           string            `validate:"contains=purpose"`
+		ContainsAny        string            `validate:"containsany=!@#$"`
+		Excludes           string            `validate:"excludes=text"`
+		ExcludesAll        string            `validate:"excludesall=!@#$"`
+		ExcludesRune       string            `validate:"excludesrune=☻"`
+		ISBN               string            `validate:"isbn"`
+		ISBN10             string            `validate:"isbn10"`
+		ISBN13             string            `validate:"isbn13"`
+		ISSN               string            `validate:"issn"`
+		UUID               string            `validate:"uuid"`
+		UUID3              string            `validate:"uuid3"`
+		UUID4              string            `validate:"uuid4"`
+		UUID5              string            `validate:"uuid5"`
+		ULID               string            `validate:"ulid"`
+		ASCII              string            `validate:"ascii"`
+		PrintableASCII     string            `validate:"printascii"`
+		MultiByte          string            `validate:"multibyte"`
+		DataURI            string            `validate:"datauri"`
+		Latitude           string            `validate:"latitude"`
+		Longitude          string            `validate:"longitude"`
+		SSN                string            `validate:"ssn"`
+		IP                 string            `validate:"ip"`
+		IPv4               string            `validate:"ipv4"`
+		IPv6               string            `validate:"ipv6"`
+		CIDR               string            `validate:"cidr"`
+		CIDRv4             string            `validate:"cidrv4"`
+		CIDRv6             string            `validate:"cidrv6"`
+		TCPAddr            string            `validate:"tcp_addr"`
+		TCPAddrv4          string            `validate:"tcp4_addr"`
+		TCPAddrv6          string            `validate:"tcp6_addr"`
+		UDPAddr            string            `validate:"udp_addr"`
+		UDPAddrv4          string            `validate:"udp4_addr"`
+		UDPAddrv6          string            `validate:"udp6_addr"`
+		IPAddr             string            `validate:"ip_addr"`
+		IPAddrv4           string            `validate:"ip4_addr"`
+		IPAddrv6           string            `validate:"ip6_addr"`
+		UinxAddr           string            `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
+		MAC                string            `validate:"mac"`
+		FQDN               string            `validate:"fqdn"`
+		IsColor            string            `validate:"iscolor"`
+		StrPtrMinLen       *string           `validate:"min=10"`
+		StrPtrMaxLen       *string           `validate:"max=1"`
+		StrPtrLen          *string           `validate:"len=2"`
+		StrPtrLt           *string           `validate:"lt=1"`
+		StrPtrLte          *string           `validate:"lte=1"`
+		StrPtrGt           *string           `validate:"gt=10"`
+		StrPtrGte          *string           `validate:"gte=10"`
+		OneOfString        string            `validate:"oneof=red green"`
+		OneOfInt           int               `validate:"oneof=5 63"`
+		UniqueSlice        []string          `validate:"unique"`
+		UniqueArray        [3]string         `validate:"unique"`
+		UniqueMap          map[string]string `validate:"unique"`
+		JSONString         string            `validate:"json"`
+		JWTString          string            `validate:"jwt"`
+		LowercaseString    string            `validate:"lowercase"`
+		UppercaseString    string            `validate:"uppercase"`
+		Datetime           string            `validate:"datetime=2006-01-02"`
+		PostCode           string            `validate:"postcode_iso3166_alpha2=SG"`
+		PostCodeCountry    string
+		PostCodeByField    string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
+		BooleanString      string `validate:"boolean"`
+		Image              string `validate:"image"`
+		CveString          string `validate:"cve"`
 	}
 
 	var test Test
@@ -163,6 +186,20 @@ func TestTranslations(t *testing.T) {
 	test.Inner.EqCSFieldString = "1234"
 	test.Inner.GtCSFieldString = "1234"
 	test.Inner.GteCSFieldString = "1234"
+	test.Inner.RequiredUnless = "1234"
+	test.Inner.RequiredWith = "1234"
+	test.Inner.RequiredWithAll = "1234"
+	test.Inner.ExcludedIf = "abcd"
+	test.Inner.ExcludedUnless = "1234"
+	test.Inner.ExcludedWith = "1234"
+	test.Inner.ExcludedWithAll = "1234"
+
+	test.ExcludedIf = "1234"
+	test.ExcludedUnless = "1234"
+	test.ExcludedWith = "1234"
+	test.ExcludedWithAll = "1234"
+	test.ExcludedWithout = "1234"
+	test.ExcludedWithoutAll = "1234"
 
 	test.MaxString = "1234"
 	test.MaxNumber = 2000
@@ -623,6 +660,50 @@ func TestTranslations(t *testing.T) {
 			ns:       "Test.RequiredMultiple",
 			expected: "RequiredMultiple is a required field",
 		},
+		{
+			ns:       "Test.RequiredUnless",
+			expected: "RequiredUnless is a required field",
+		},
+		{
+			ns:       "Test.RequiredWith",
+			expected: "RequiredWith is a required field",
+		},
+		{
+			ns:       "Test.RequiredWithAll",
+			expected: "RequiredWithAll is a required field",
+		},
+		{
+			ns:       "Test.RequiredWithout",
+			expected: "RequiredWithout is a required field",
+		},
+		{
+			ns:       "Test.RequiredWithoutAll",
+			expected: "RequiredWithoutAll is a required field",
+		},
+		{
+			ns:       "Test.ExcludedIf",
+			expected: "ExcludedIf is an excluded field",
+		},
+		{
+			ns:       "Test.ExcludedUnless",
+			expected: "ExcludedUnless is an excluded field",
+		},
+		{
+			ns:       "Test.ExcludedWith",
+			expected: "ExcludedWith is an excluded field",
+		},
+		{
+			ns:       "Test.ExcludedWithAll",
+			expected: "ExcludedWithAll is an excluded field",
+		},
+		{
+			ns:       "Test.ExcludedWithout",
+			expected: "ExcludedWithout is an excluded field",
+		},
+		{
+			ns:       "Test.ExcludedWithoutAll",
+			expected: "ExcludedWithoutAll is an excluded field",
+		},
 		{
 			ns:       "Test.StrPtrMinLen",
 			expected: "StrPtrMinLen must be at least 10 characters in length",
diff --git a/translations/zh/zh_test.go b/translations/zh/zh_test.go
index 2b8ee05..e8af017 100644
--- a/translations/zh/zh_test.go
+++ b/translations/zh/zh_test.go
@@ -22,12 +22,24 @@ func TestTranslations(t *testing.T) {
 	Equal(t, err, nil)
 
 	type Inner struct {
-		EqCSFieldString  string
-		NeCSFieldString  string
-		GtCSFieldString  string
-		GteCSFieldString string
-		LtCSFieldString  string
-		LteCSFieldString string
+		EqCSFieldString    string
+		NeCSFieldString    string
+		GtCSFieldString    string
+		GteCSFieldString   string
+		LtCSFieldString    string
+		LteCSFieldString   string
+		RequiredIf         string
+		RequiredUnless     string
+		RequiredWith       string
+		RequiredWithAll    string
+		RequiredWithout    string
+		RequiredWithoutAll string
+		ExcludedIf         string
+		ExcludedUnless     string
+		ExcludedWith       string
+		ExcludedWithAll    string
+		ExcludedWithout    string
+		ExcludedWithoutAll string
 	}
 
 	type Test struct {
@@ -35,6 +47,19 @@ func TestTranslations(t *testing.T) {
 		RequiredString        string    `validate:"required"`
 		RequiredNumber        int       `validate:"required"`
 		RequiredMultiple      []string  `validate:"required"`
+		RequiredIf            string    `validate:"required_if=Inner.RequiredIf abcd"`
+		RequiredUnless        string    `validate:"required_unless=Inner.RequiredUnless abcd"`
+		RequiredWith          string    `validate:"required_with=Inner.RequiredWith"`
+		RequiredWithAll       string    `validate:"required_with_all=Inner.RequiredWith Inner.RequiredWithAll"`
+		RequiredWithout       string    `validate:"required_without=Inner.RequiredWithout"`
+		RequiredWithoutAll    string    `validate:"required_without_all=Inner.RequiredWithout Inner.RequiredWithoutAll"`
+		ExcludedIf            string    `validate:"excluded_if=Inner.ExcludedIf abcd"`
+		ExcludedUnless        string    `validate:"excluded_unless=Inner.ExcludedUnless abcd"`
+		ExcludedWith          string    `validate:"excluded_with=Inner.ExcludedWith"`
+		ExcludedWithout       string    `validate:"excluded_with_all=Inner.ExcludedWithAll"`
+		ExcludedWithAll       string    `validate:"excluded_without=Inner.ExcludedWithout"`
+		ExcludedWithoutAll    string    `validate:"excluded_without_all=Inner.ExcludedWithoutAll"`
+		IsDefault             string    `validate:"isdefault"`
 		LenString             string    `validate:"len=1"`
 		LenNumber             float64   `validate:"len=1113.00"`
 		LenMultiple           []string  `validate:"len=7"`
@@ -149,7 +174,7 @@ func TestTranslations(t *testing.T) {
 		LowercaseString       string    `validate:"lowercase"`
 		UppercaseString       string    `validate:"uppercase"`
 		Datetime              string    `validate:"datetime=2006-01-02"`
-		Image			  string			`validate:"image"`
+		Image                 string    `validate:"image"`
 	}
 
 	var test Test
@@ -157,6 +182,21 @@ func TestTranslations(t *testing.T) {
 	test.Inner.EqCSFieldString = "1234"
 	test.Inner.GtCSFieldString = "1234"
 	test.Inner.GteCSFieldString = "1234"
+	test.Inner.RequiredIf = "abcd"
+	test.Inner.RequiredUnless = "1234"
+	test.Inner.RequiredWith = "1234"
+	test.Inner.RequiredWithAll = "1234"
+	test.Inner.ExcludedIf = "abcd"
+	test.Inner.ExcludedUnless = "1234"
+	test.Inner.ExcludedWith = "1234"
+	test.Inner.ExcludedWithAll = "1234"
+
+	test.ExcludedIf = "1234"
+	test.ExcludedUnless = "1234"
+	test.ExcludedWith = "1234"
+	test.ExcludedWithAll = "1234"
+	test.ExcludedWithout = "1234"
+	test.ExcludedWithoutAll = "1234"
 
 	test.MaxString = "1234"
 	test.MaxNumber = 2000
@@ -630,6 +670,50 @@ func TestTranslations(t *testing.T) {
 			ns:       "Test.RequiredMultiple",
 			expected: "RequiredMultiple为必填字段",
 		},
+		{
+			ns:       "Test.RequiredUnless",
+			expected: "RequiredUnless为必填字段",
+		},
+		{
+			ns:       "Test.RequiredWith",
+			expected: "RequiredWith为必填字段",
+		},
+		{
+			ns:       "Test.RequiredWithAll",
+			expected: "RequiredWithAll为必填字段",
+		},
+		{
+			ns:       "Test.RequiredWithout",
+			expected: "RequiredWithout为必填字段",
+		},
+		{
+			ns:       "Test.RequiredWithoutAll",
+			expected: "RequiredWithoutAll为必填字段",
+		},
+		{
+			ns:       "Test.ExcludedIf",
+			expected: "ExcludedIf为禁填字段",
+		},
+		{
+			ns:       "Test.ExcludedUnless",
+			expected: "ExcludedUnless为禁填字段",
+		},
+		{
+			ns:       "Test.ExcludedWith",
+			expected: "ExcludedWith为禁填字段",
+		},
+		{
+			ns:       "Test.ExcludedWithAll",
+			expected: "ExcludedWithAll为禁填字段",
+		},
+		{
+			ns:       "Test.ExcludedWithout",
+			expected: "ExcludedWithout为禁填字段",
+		},
+		{
+			ns:       "Test.ExcludedWithoutAll",
+			expected: "ExcludedWithoutAll为禁填字段",
+		},
 		{
 			ns:       "Test.StrPtrMinLen",
 			expected: "StrPtrMinLen长度必须至少为10个字符",
@@ -683,7 +767,7 @@ func TestTranslations(t *testing.T) {
 			expected: "Datetime的格式必须是2006-01-02",
 		},
 		{
-			ns: "Test.Image",
+			ns:       "Test.Image",
 			expected: "Image 必须是有效图像",
 		},
 	}
diff --git a/translations/zh_tw/zh_tw_test.go b/translations/zh_tw/zh_tw_test.go
index e106363..1385c19 100644
--- a/translations/zh_tw/zh_tw_test.go
+++ b/translations/zh_tw/zh_tw_test.go
@@ -28,6 +28,18 @@ func TestTranslations(t *testing.T) {
 		GteCSFieldString string
 		LtCSFieldString  string
 		LteCSFieldString string
+		RequiredIf         string
+		RequiredUnless     string
+		RequiredWith       string
+		RequiredWithAll    string
+		RequiredWithout    string
+		RequiredWithoutAll string
+		ExcludedIf         string
+		ExcludedUnless     string
+		ExcludedWith       string
+		ExcludedWithAll    string
+		ExcludedWithout    string
+		ExcludedWithoutAll string
 	}
 
 	type Test struct {
@@ -35,6 +47,19 @@ func TestTranslations(t *testing.T) {
 		RequiredString    string    `validate:"required"`
 		RequiredNumber    int       `validate:"required"`
 		RequiredMultiple  []string  `validate:"required"`
+		RequiredIf             string    `validate:"required_if=Inner.RequiredIf abcd"`
+		RequiredUnless        string    `validate:"required_unless=Inner.RequiredUnless abcd"`
+		RequiredWith          string    `validate:"required_with=Inner.RequiredWith"`
+		RequiredWithAll       string    `validate:"required_with_all=Inner.RequiredWith Inner.RequiredWithAll"`
+		RequiredWithout       string    `validate:"required_without=Inner.RequiredWithout"`
+		RequiredWithoutAll    string    `validate:"required_without_all=Inner.RequiredWithout Inner.RequiredWithoutAll"`
+		ExcludedIf            string    `validate:"excluded_if=Inner.ExcludedIf abcd"`
+		ExcludedUnless        string    `validate:"excluded_unless=Inner.ExcludedUnless abcd"`
+		ExcludedWith          string    `validate:"excluded_with=Inner.ExcludedWith"`
+		ExcludedWithout       string    `validate:"excluded_with_all=Inner.ExcludedWithAll"`
+		ExcludedWithAll       string    `validate:"excluded_without=Inner.ExcludedWithout"`
+		ExcludedWithoutAll    string    `validate:"excluded_without_all=Inner.ExcludedWithoutAll"`
+		IsDefault             string    `validate:"isdefault"`
 		LenString         string    `validate:"len=1"`
 		LenNumber         float64   `validate:"len=1113.00"`
 		LenMultiple       []string  `validate:"len=7"`
@@ -149,6 +174,21 @@ func TestTranslations(t *testing.T) {
 	test.Inner.EqCSFieldString = "1234"
 	test.Inner.GtCSFieldString = "1234"
 	test.Inner.GteCSFieldString = "1234"
+	test.Inner.RequiredIf = "abcd"
+	test.Inner.RequiredUnless = "1234"
+	test.Inner.RequiredWith = "1234"
+	test.Inner.RequiredWithAll = "1234"
+	test.Inner.ExcludedIf = "abcd"
+	test.Inner.ExcludedUnless = "1234"
+	test.Inner.ExcludedWith = "1234"
+	test.Inner.ExcludedWithAll = "1234"
+
+	test.ExcludedIf = "1234"
+	test.ExcludedUnless = "1234"
+	test.ExcludedWith = "1234"
+	test.ExcludedWithAll = "1234"
+	test.ExcludedWithout = "1234"
+	test.ExcludedWithoutAll = "1234"
 
 	test.MaxString = "1234"
 	test.MaxNumber = 2000
@@ -592,6 +632,50 @@ func TestTranslations(t *testing.T) {
 			ns:       "Test.RequiredMultiple",
 			expected: "RequiredMultiple為必填欄位",
 		},
+		{
+			ns:       "Test.RequiredUnless",
+			expected: "RequiredUnless為必填欄位",
+		},
+		{
+			ns:       "Test.RequiredWith",
+			expected: "RequiredWith為必填欄位",
+		},
+		{
+			ns:       "Test.RequiredWithAll",
+			expected: "RequiredWithAll為必填欄位",
+		},
+		{
+			ns:       "Test.RequiredWithout",
+			expected: "RequiredWithout為必填欄位",
+		},
+		{
+			ns:       "Test.RequiredWithoutAll",
+			expected: "RequiredWithoutAll為必填欄位",
+		},
+		{
+			ns:       "Test.ExcludedIf",
+			expected: "ExcludedIf為禁填欄位",
+		},
+		{
+			ns:       "Test.ExcludedUnless",
+			expected: "ExcludedUnless為禁填欄位",
+		},
+		{
+			ns:       "Test.ExcludedWith",
+			expected: "ExcludedWith為禁填欄位",
+		},
+		{
+			ns:       "Test.ExcludedWithAll",
+			expected: "ExcludedWithAll為禁填欄位",
+		},
+		{
+			ns:       "Test.ExcludedWithout",
+			expected: "ExcludedWithout為禁填欄位",
+		},
+		{
+			ns:       "Test.ExcludedWithoutAll",
+			expected: "ExcludedWithoutAll為禁填欄位",
+		},
 		{
 			ns:       "Test.StrPtrMinLen",
 			expected: "StrPtrMinLen長度必須至少為10個字元",
diff --git a/validator_test.go b/validator_test.go
index 2826ae7..7144f83 100644
--- a/validator_test.go
+++ b/validator_test.go
@@ -4338,7 +4338,7 @@ func TestULIDValidation(t *testing.T) {
 	}{
 		{"", false},
 		{"01BX5ZZKBKACT-V9WEVGEMMVRZ", false},
-		{"01bx5zzkbkactav9wevgemmvrz", false},
+		{"01bx5zzkbkactav9wevgemmvrz", true},
 		{"a987Fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
 		{"01BX5ZZKBKACTAV9WEVGEMMVRZABC", false},
 		{"01BX5ZZKBKACTAV9WEVGEMMVRZABC", false},
@@ -5680,6 +5680,40 @@ func TestOneOfValidation(t *testing.T) {
 	}, "Bad field type float64")
 }
 
+func TestBase32Validation(t *testing.T) {
+	validate := New()
+
+	s := "ABCD2345"
+	errs := validate.Var(s, "base32")
+	Equal(t, errs, nil)
+
+	s = "AB======"
+	errs = validate.Var(s, "base32")
+	Equal(t, errs, nil)
+
+	s = "ABCD2==="
+	errs = validate.Var(s, "base32")
+	Equal(t, errs, nil)
+
+	s = "ABCD===="
+	errs = validate.Var(s, "base32")
+	Equal(t, errs, nil)
+
+	s = "ABCD234="
+	errs = validate.Var(s, "base32")
+	Equal(t, errs, nil)
+
+	s = ""
+	errs = validate.Var(s, "base32")
+	NotEqual(t, errs, nil)
+	AssertError(t, errs, "", "", "", "", "base32")
+
+	s = "ABCabc1890== foo bar"
+	errs = validate.Var(s, "base32")
+	NotEqual(t, errs, nil)
+	AssertError(t, errs, "", "", "", "", "base32")
+}
+
 func TestBase64Validation(t *testing.T) {
 	validate := New()
 
@@ -12482,6 +12516,33 @@ func TestIsIso3166Alpha2Validation(t *testing.T) {
 	}
 }
 
+func TestIsIso3166Alpha2EUValidation(t *testing.T) {
+	tests := []struct {
+		value    string `validate:"iso3166_1_alpha2_eu"`
+		expected bool
+	}{
+		{"SE", true},
+		{"UK", false},
+	}
+
+	validate := New()
+
+	for i, test := range tests {
+
+		errs := validate.Var(test.value, "iso3166_1_alpha2_eu")
+
+		if test.expected {
+			if !IsEqual(errs, nil) {
+				t.Fatalf("Index: %d iso3166_1_alpha2_eu failed Error: %s", i, errs)
+			}
+		} else {
+			if IsEqual(errs, nil) {
+				t.Fatalf("Index: %d iso3166_1_alpha2_eu failed Error: %s", i, errs)
+			}
+		}
+	}
+}
+
 func TestIsIso31662Validation(t *testing.T) {
 	tests := []struct {
 		value    string `validate:"iso3166_2"`
@@ -12538,6 +12599,34 @@ func TestIsIso3166Alpha3Validation(t *testing.T) {
 	}
 }
 
+func TestIsIso3166Alpha3EUValidation(t *testing.T) {
+	tests := []struct {
+		value    string `validate:"iso3166_1_alpha3_eu"`
+		expected bool
+	}{
+		{"POL", true},
+		{"SWE", true},
+		{"UNK", false},
+	}
+
+	validate := New()
+
+	for i, test := range tests {
+
+		errs := validate.Var(test.value, "iso3166_1_alpha3_eu")
+
+		if test.expected {
+			if !IsEqual(errs, nil) {
+				t.Fatalf("Index: %d iso3166_1_alpha3_eu failed Error: %s", i, errs)
+			}
+		} else {
+			if IsEqual(errs, nil) {
+				t.Fatalf("Index: %d iso3166_1_alpha3_eu failed Error: %s", i, errs)
+			}
+		}
+	}
+}
+
 func TestIsIso3166AlphaNumericValidation(t *testing.T) {
 	tests := []struct {
 		value    interface{}
@@ -12573,6 +12662,39 @@ func TestIsIso3166AlphaNumericValidation(t *testing.T) {
 	}, "Bad field type []string")
 }
 
+func TestIsIso3166AlphaNumericEUValidation(t *testing.T) {
+	tests := []struct {
+		value    interface{}
+		expected bool
+	}{
+		{752, true}, //Sweden
+		{"752", true},
+		{826, false}, // UK
+		{"826", false},
+	}
+
+	validate := New()
+
+	for i, test := range tests {
+
+		errs := validate.Var(test.value, "iso3166_1_alpha_numeric_eu")
+
+		if test.expected {
+			if !IsEqual(errs, nil) {
+				t.Fatalf("Index: %d iso3166_1_alpha_numeric_eu failed Error: %s", i, errs)
+			}
+		} else {
+			if IsEqual(errs, nil) {
+				t.Fatalf("Index: %d iso3166_1_alpha_numeric_eu failed Error: %s", i, errs)
+			}
+		}
+	}
+
+	PanicMatches(t, func() {
+		_ = validate.Var([]string{"1"}, "iso3166_1_alpha_numeric_eu")
+	}, "Bad field type []string")
+}
+
 func TestCountryCodeValidation(t *testing.T) {
 	tests := []struct {
 		value    interface{}
@@ -12606,6 +12728,39 @@ func TestCountryCodeValidation(t *testing.T) {
 	}
 }
 
+func TestEUCountryCodeValidation(t *testing.T) {
+	tests := []struct {
+		value    interface{}
+		expected bool
+	}{
+		{724, true},
+		{0, false},
+		{1, false},
+		{"POL", true},
+		{"NO", false},
+		{"724", true},
+		{"1", false},
+		{"0", false},
+	}
+
+	validate := New()
+
+	for i, test := range tests {
+
+		errs := validate.Var(test.value, "eu_country_code")
+
+		if test.expected {
+			if !IsEqual(errs, nil) {
+				t.Fatalf("Index: %d eu_country_code failed Error: %s", i, errs)
+			}
+		} else {
+			if IsEqual(errs, nil) {
+				t.Fatalf("Index: %d eu_country_code failed Error: %s", i, errs)
+			}
+		}
+	}
+}
+
 func TestIsIso4217Validation(t *testing.T) {
 	tests := []struct {
 		value    string `validate:"iso4217"`
@@ -13231,6 +13386,58 @@ func TestMongoDBObjectIDFormatValidation(t *testing.T) {
 		}
 	}
 }
+func TestMongoDBConnectionStringFormatValidation(t *testing.T) {
+	tests := []struct {
+		value    string `validate:"mongodb_connection_string"`
+		tag      string
+		expected bool
+	}{
+		{"mongodb://username:password@server.example.com:20017/database?replicaSet=test&connectTimeoutMS=300000&ssl=true", "mongodb_connection_string", true},
+		{"mongodb+srv://username:password@server.example.com:20017/database?replicaSet=test&connectTimeoutMS=300000&ssl=true", "mongodb_connection_string", true},
+		{"mongodb+srv://username:password@server.example.com:20017,server.example.com,server.example.com:20017/database?replicaSet=test&connectTimeoutMS=300000&ssl=true", "mongodb_connection_string", true},
+		{"mongodb+srv://username:password@server.example.com:20017,server.example.com,server.example.com:20017?replicaSet=test&connectTimeoutMS=300000&ssl=true", "mongodb_connection_string", true},
+		{"mongodb://username:password@server.example.com:20017,server.example.com,server.example.com:20017/database?replicaSet=test&connectTimeoutMS=300000&ssl=true", "mongodb_connection_string", true},
+		{"mongodb://localhost", "mongodb_connection_string", true},
+		{"mongodb://localhost:27017", "mongodb_connection_string", true},
+		{"localhost", "mongodb_connection_string", false},
+		{"mongodb://", "mongodb_connection_string", false},
+		{"mongodb+srv://", "mongodb_connection_string", false},
+		{"mongodbsrv://localhost", "mongodb_connection_string", false},
+		{"mongodb+srv://localhost", "mongodb_connection_string", true},
+		{"mongodb+srv://localhost:27017", "mongodb_connection_string", true},
+		{"mongodb+srv://localhost?replicaSet=test", "mongodb_connection_string", true},
+		{"mongodb+srv://localhost:27017?replicaSet=test", "mongodb_connection_string", true},
+		{"mongodb+srv://localhost:27017?", "mongodb_connection_string", false},
+		{"mongodb+srv://localhost:27017?replicaSet", "mongodb_connection_string", false},
+		{"mongodb+srv://localhost/database", "mongodb_connection_string", true},
+		{"mongodb+srv://localhost:27017/database", "mongodb_connection_string", true},
+		{"mongodb+srv://username@localhost", "mongodb_connection_string", false},
+		{"mongodb+srv://username:password@localhost", "mongodb_connection_string", true},
+		{"mongodb+srv://username:password@localhost:27017", "mongodb_connection_string", true},
+		{"mongodb+srv://username:password@localhost:27017,192.0.0.7,192.0.0.9:27018,server.example.com", "mongodb_connection_string", true},
+	}
+
+	validate := New()
+
+	for i, test := range tests {
+		errs := validate.Var(test.value, test.tag)
+
+		if test.expected {
+			if !IsEqual(errs, nil) {
+				t.Fatalf("Index: %d mongodb_connection_string failed Error: %s", i, errs)
+			}
+		} else {
+			if IsEqual(errs, nil) {
+				t.Fatalf("Index: %d mongodb_connection_string failed Error: %s", i, errs)
+			} else {
+				val := getError(errs, "", "")
+				if val.Tag() != "mongodb_connection_string" {
+					t.Fatalf("Index: %d mongodb_connection_string failed Error: %s", i, errs)
+				}
+			}
+		}
+	}
+}
 
 func TestSpiceDBValueFormatValidation(t *testing.T) {
 	tests := []struct {
@@ -13692,3 +13899,105 @@ func TestOmitNilAndRequired(t *testing.T) {
 		AssertError(t, err2, "OmitNil.Inner.Str", "OmitNil.Inner.Str", "Str", "Str", "required")
 	})
 }
+
+func TestPrivateFieldsStruct(t *testing.T) {
+	type tc struct {
+		stct     interface{}
+		errorNum int
+	}
+
+	tcs := []tc{
+		{
+			stct: &struct {
+				f1 int8  `validate:"required"`
+				f2 int16 `validate:"required"`
+				f3 int32 `validate:"required"`
+				f4 int64 `validate:"required"`
+			}{},
+			errorNum: 4,
+		},
+		{
+			stct: &struct {
+				f1 uint8  `validate:"required"`
+				f2 uint16 `validate:"required"`
+				f3 uint32 `validate:"required"`
+				f4 uint64 `validate:"required"`
+			}{},
+			errorNum: 4,
+		},
+		{
+			stct: &struct {
+				f1 complex64  `validate:"required"`
+				f2 complex128 `validate:"required"`
+			}{},
+			errorNum: 2,
+		},
+		{
+			stct: &struct {
+				f1 float32 `validate:"required"`
+				f2 float64 `validate:"required"`
+			}{},
+			errorNum: 2,
+		},
+		{
+			stct: struct {
+				f1 int8  `validate:"required"`
+				f2 int16 `validate:"required"`
+				f3 int32 `validate:"required"`
+				f4 int64 `validate:"required"`
+			}{},
+			errorNum: 4,
+		},
+		{
+			stct: struct {
+				f1 uint8  `validate:"required"`
+				f2 uint16 `validate:"required"`
+				f3 uint32 `validate:"required"`
+				f4 uint64 `validate:"required"`
+			}{},
+			errorNum: 4,
+		},
+		{
+			stct: struct {
+				f1 complex64  `validate:"required"`
+				f2 complex128 `validate:"required"`
+			}{},
+			errorNum: 2,
+		},
+		{
+			stct: struct {
+				f1 float32 `validate:"required"`
+				f2 float64 `validate:"required"`
+			}{},
+			errorNum: 2,
+		},
+		{
+			stct: struct {
+				f1 *int `validate:"required"`
+				f2 struct {
+					f3 int `validate:"required"`
+				}
+			}{},
+			errorNum: 2,
+		},
+		{
+			stct: &struct {
+				f1 *int `validate:"required"`
+				f2 struct {
+					f3 int `validate:"required"`
+				}
+			}{},
+			errorNum: 2,
+		},
+	}
+
+	validate := New(WithPrivateFieldValidation())
+
+	for _, tc := range tcs {
+		err := validate.Struct(tc.stct)
+		NotEqual(t, err, nil)
+
+		errs := err.(ValidationErrors)
+		Equal(t, len(errs), tc.errorNum)
+	}
+}