• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.circleci/H08-Jan-2020-

.github/H08-Jan-2020-

.gitignoreH A D08-Jan-2020205

.travis.ymlH A D08-Jan-2020393

CONTRIBUTING.mdH A D08-Jan-20204.2 KiB

LICENSEH A D08-Jan-20201.1 KiB

README.mdH A D08-Jan-202023.4 KiB

arrays.goH A D08-Jan-20201.9 KiB

arrays_test.goH A D08-Jan-20202.9 KiB

converter.goH A D08-Jan-20201.4 KiB

converter_test.goH A D08-Jan-20202.3 KiB

doc.goH A D08-Jan-2020104

error.goH A D08-Jan-2020904

error_test.goH A D08-Jan-2020911

go.modH A D08-Jan-202050

numerics.goH A D08-Jan-20202.7 KiB

numerics_test.goH A D08-Jan-202011.8 KiB

patterns.goH A D08-Jan-20207.7 KiB

types.goH A D08-Jan-202033.3 KiB

utils.goH A D08-Jan-20207.8 KiB

utils_benchmark_test.goH A D08-Jan-2020353

utils_test.goH A D08-Jan-202012.9 KiB

validator.goH A D08-Jan-202041.4 KiB

validator_test.goH A D08-Jan-2020113.5 KiB

wercker.ymlH A D08-Jan-2020238

README.md

1govalidator
2===========
3[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![GoDoc](https://godoc.org/github.com/asaskevich/govalidator?status.png)](https://godoc.org/github.com/asaskevich/govalidator) [![Coverage Status](https://img.shields.io/coveralls/asaskevich/govalidator.svg)](https://coveralls.io/r/asaskevich/govalidator?branch=master) [![wercker status](https://app.wercker.com/status/1ec990b09ea86c910d5f08b0e02c6043/s "wercker status")](https://app.wercker.com/project/bykey/1ec990b09ea86c910d5f08b0e02c6043)
4[![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator) [![Go Report Card](https://goreportcard.com/badge/github.com/asaskevich/govalidator)](https://goreportcard.com/report/github.com/asaskevich/govalidator) [![GoSearch](http://go-search.org/badge?id=github.com%2Fasaskevich%2Fgovalidator)](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [![Backers on Open Collective](https://opencollective.com/govalidator/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/govalidator/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield)
5
6A package of validators and sanitizers for strings, structs and collections. Based on [validator.js](https://github.com/chriso/validator.js).
7
8#### Installation
9Make sure that Go is installed on your computer.
10Type the following command in your terminal:
11
12	go get github.com/asaskevich/govalidator
13
14or you can get specified release of the package with `gopkg.in`:
15
16	go get gopkg.in/asaskevich/govalidator.v10
17
18After it the package is ready to use.
19
20
21#### Import package in your project
22Add following line in your `*.go` file:
23```go
24import "github.com/asaskevich/govalidator"
25```
26If you are unhappy to use long `govalidator`, you can do something like this:
27```go
28import (
29  valid "github.com/asaskevich/govalidator"
30)
31```
32
33#### Activate behavior to require all fields have a validation tag by default
34`SetFieldsRequiredByDefault` causes validation to fail when struct fields do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). A good place to activate this is a package init function or the main() function.
35
36`SetNilPtrAllowedByRequired` causes validation to pass when struct fields marked by `required` are set to nil. This is disabled by default for consistency, but some packages that need to be able to determine between `nil` and `zero value` state can use this. If disabled, both `nil` and `zero` values cause validation errors.
37
38```go
39import "github.com/asaskevich/govalidator"
40
41func init() {
42  govalidator.SetFieldsRequiredByDefault(true)
43}
44```
45
46Here's some code to explain it:
47```go
48// this struct definition will fail govalidator.ValidateStruct() (and the field values do not matter):
49type exampleStruct struct {
50  Name  string ``
51  Email string `valid:"email"`
52}
53
54// this, however, will only fail when Email is empty or an invalid email address:
55type exampleStruct2 struct {
56  Name  string `valid:"-"`
57  Email string `valid:"email"`
58}
59
60// lastly, this will only fail when Email is an invalid email address but not when it's empty:
61type exampleStruct2 struct {
62  Name  string `valid:"-"`
63  Email string `valid:"email,optional"`
64}
65```
66
67#### Recent breaking changes (see [#123](https://github.com/asaskevich/govalidator/pull/123))
68##### Custom validator function signature
69A context was added as the second parameter, for structs this is the object being validated – this makes dependent validation possible.
70```go
71import "github.com/asaskevich/govalidator"
72
73// old signature
74func(i interface{}) bool
75
76// new signature
77func(i interface{}, o interface{}) bool
78```
79
80##### Adding a custom validator
81This was changed to prevent data races when accessing custom validators.
82```go
83import "github.com/asaskevich/govalidator"
84
85// before
86govalidator.CustomTypeTagMap["customByteArrayValidator"] = CustomTypeValidator(func(i interface{}, o interface{}) bool {
87  // ...
88})
89
90// after
91govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
92  // ...
93}))
94```
95
96#### List of functions:
97```go
98func Abs(value float64) float64
99func BlackList(str, chars string) string
100func ByteLength(str string, params ...string) bool
101func CamelCaseToUnderscore(str string) string
102func Contains(str, substring string) bool
103func Count(array []interface{}, iterator ConditionIterator) int
104func Each(array []interface{}, iterator Iterator)
105func ErrorByField(e error, field string) string
106func ErrorsByField(e error) map[string]string
107func Filter(array []interface{}, iterator ConditionIterator) []interface{}
108func Find(array []interface{}, iterator ConditionIterator) interface{}
109func GetLine(s string, index int) (string, error)
110func GetLines(s string) []string
111func HasLowerCase(str string) bool
112func HasUpperCase(str string) bool
113func HasWhitespace(str string) bool
114func HasWhitespaceOnly(str string) bool
115func InRange(value interface{}, left interface{}, right interface{}) bool
116func InRangeFloat32(value, left, right float32) bool
117func InRangeFloat64(value, left, right float64) bool
118func InRangeInt(value, left, right interface{}) bool
119func IsASCII(str string) bool
120func IsAlpha(str string) bool
121func IsAlphanumeric(str string) bool
122func IsBase64(str string) bool
123func IsByteLength(str string, min, max int) bool
124func IsCIDR(str string) bool
125func IsCRC32(str string) bool
126func IsCRC32b(str string) bool
127func IsCreditCard(str string) bool
128func IsDNSName(str string) bool
129func IsDataURI(str string) bool
130func IsDialString(str string) bool
131func IsDivisibleBy(str, num string) bool
132func IsEmail(str string) bool
133func IsExistingEmail(email string) bool
134func IsFilePath(str string) (bool, int)
135func IsFloat(str string) bool
136func IsFullWidth(str string) bool
137func IsHalfWidth(str string) bool
138func IsHash(str string, algorithm string) bool
139func IsHexadecimal(str string) bool
140func IsHexcolor(str string) bool
141func IsHost(str string) bool
142func IsIP(str string) bool
143func IsIPv4(str string) bool
144func IsIPv6(str string) bool
145func IsISBN(str string, version int) bool
146func IsISBN10(str string) bool
147func IsISBN13(str string) bool
148func IsISO3166Alpha2(str string) bool
149func IsISO3166Alpha3(str string) bool
150func IsISO4217(str string) bool
151func IsISO693Alpha2(str string) bool
152func IsISO693Alpha3b(str string) bool
153func IsIn(str string, params ...string) bool
154func IsInRaw(str string, params ...string) bool
155func IsInt(str string) bool
156func IsJSON(str string) bool
157func IsLatitude(str string) bool
158func IsLongitude(str string) bool
159func IsLowerCase(str string) bool
160func IsMAC(str string) bool
161func IsMD4(str string) bool
162func IsMD5(str string) bool
163func IsMagnetURI(str string) bool
164func IsMongoID(str string) bool
165func IsMultibyte(str string) bool
166func IsNatural(value float64) bool
167func IsNegative(value float64) bool
168func IsNonNegative(value float64) bool
169func IsNonPositive(value float64) bool
170func IsNotNull(str string) bool
171func IsNull(str string) bool
172func IsNumeric(str string) bool
173func IsPort(str string) bool
174func IsPositive(value float64) bool
175func IsPrintableASCII(str string) bool
176func IsRFC3339(str string) bool
177func IsRFC3339WithoutZone(str string) bool
178func IsRGBcolor(str string) bool
179func IsRequestURI(rawurl string) bool
180func IsRequestURL(rawurl string) bool
181func IsRipeMD128(str string) bool
182func IsRipeMD160(str string) bool
183func IsRsaPub(str string, params ...string) bool
184func IsRsaPublicKey(str string, keylen int) bool
185func IsSHA1(str string) bool
186func IsSHA256(str string) bool
187func IsSHA384(str string) bool
188func IsSHA512(str string) bool
189func IsSSN(str string) bool
190func IsSemver(str string) bool
191func IsTiger128(str string) bool
192func IsTiger160(str string) bool
193func IsTiger192(str string) bool
194func IsTime(str string, format string) bool
195func IsType(v interface{}, params ...string) bool
196func IsURL(str string) bool
197func IsUTFDigit(str string) bool
198func IsUTFLetter(str string) bool
199func IsUTFLetterNumeric(str string) bool
200func IsUTFNumeric(str string) bool
201func IsUUID(str string) bool
202func IsUUIDv3(str string) bool
203func IsUUIDv4(str string) bool
204func IsUUIDv5(str string) bool
205func IsUnixTime(str string) bool
206func IsUpperCase(str string) bool
207func IsVariableWidth(str string) bool
208func IsWhole(value float64) bool
209func LeftTrim(str, chars string) string
210func Map(array []interface{}, iterator ResultIterator) []interface{}
211func Matches(str, pattern string) bool
212func MaxStringLength(str string, params ...string) bool
213func MinStringLength(str string, params ...string) bool
214func NormalizeEmail(str string) (string, error)
215func PadBoth(str string, padStr string, padLen int) string
216func PadLeft(str string, padStr string, padLen int) string
217func PadRight(str string, padStr string, padLen int) string
218func PrependPathToErrors(err error, path string) error
219func Range(str string, params ...string) bool
220func RemoveTags(s string) string
221func ReplacePattern(str, pattern, replace string) string
222func Reverse(s string) string
223func RightTrim(str, chars string) string
224func RuneLength(str string, params ...string) bool
225func SafeFileName(str string) string
226func SetFieldsRequiredByDefault(value bool)
227func SetNilPtrAllowedByRequired(value bool)
228func Sign(value float64) float64
229func StringLength(str string, params ...string) bool
230func StringMatches(s string, params ...string) bool
231func StripLow(str string, keepNewLines bool) string
232func ToBoolean(str string) (bool, error)
233func ToFloat(str string) (float64, error)
234func ToInt(value interface{}) (res int64, err error)
235func ToJSON(obj interface{}) (string, error)
236func ToString(obj interface{}) string
237func Trim(str, chars string) string
238func Truncate(str string, length int, ending string) string
239func TruncatingErrorf(str string, args ...interface{}) error
240func UnderscoreToCamelCase(s string) string
241func ValidateMap(s map[string]interface{}, m map[string]interface{}) (bool, error)
242func ValidateStruct(s interface{}) (bool, error)
243func WhiteList(str, chars string) string
244type ConditionIterator
245type CustomTypeValidator
246type Error
247func (e Error) Error() string
248type Errors
249func (es Errors) Error() string
250func (es Errors) Errors() []error
251type ISO3166Entry
252type ISO693Entry
253type InterfaceParamValidator
254type Iterator
255type ParamValidator
256type ResultIterator
257type UnsupportedTypeError
258func (e *UnsupportedTypeError) Error() string
259type Validator
260```
261
262#### Examples
263###### IsURL
264```go
265println(govalidator.IsURL(`http://user@pass:domain.com/path/page`))
266```
267###### IsType
268```go
269println(govalidator.IsType("Bob", "string"))
270println(govalidator.IsType(1, "int"))
271i := 1
272println(govalidator.IsType(&i, "*int"))
273```
274
275IsType can be used through the tag `type` which is essential for map validation:
276```go
277type User	struct {
278  Name string      `valid:"type(string)"`
279  Age  int         `valid:"type(int)"`
280  Meta interface{} `valid:"type(string)"`
281}
282result, err := govalidator.ValidateStruct(user{"Bob", 20, "meta"})
283if err != nil {
284	println("error: " + err.Error())
285}
286println(result)
287```
288###### ToString
289```go
290type User struct {
291	FirstName string
292	LastName string
293}
294
295str := govalidator.ToString(&User{"John", "Juan"})
296println(str)
297```
298###### Each, Map, Filter, Count for slices
299Each iterates over the slice/array and calls Iterator for every item
300```go
301data := []interface{}{1, 2, 3, 4, 5}
302var fn govalidator.Iterator = func(value interface{}, index int) {
303	println(value.(int))
304}
305govalidator.Each(data, fn)
306```
307```go
308data := []interface{}{1, 2, 3, 4, 5}
309var fn govalidator.ResultIterator = func(value interface{}, index int) interface{} {
310	return value.(int) * 3
311}
312_ = govalidator.Map(data, fn) // result = []interface{}{1, 6, 9, 12, 15}
313```
314```go
315data := []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
316var fn govalidator.ConditionIterator = func(value interface{}, index int) bool {
317	return value.(int)%2 == 0
318}
319_ = govalidator.Filter(data, fn) // result = []interface{}{2, 4, 6, 8, 10}
320_ = govalidator.Count(data, fn) // result = 5
321```
322###### ValidateStruct [#2](https://github.com/asaskevich/govalidator/pull/2)
323If you want to validate structs, you can use tag `valid` for any field in your structure. All validators used with this field in one tag are separated by comma. If you want to skip validation, place `-` in your tag. If you need a validator that is not on the list below, you can add it like this:
324```go
325govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
326	return str == "duck"
327})
328```
329For completely custom validators (interface-based), see below.
330
331Here is a list of available validators for struct fields (validator - used function):
332```go
333"email":              IsEmail,
334"url":                IsURL,
335"dialstring":         IsDialString,
336"requrl":             IsRequestURL,
337"requri":             IsRequestURI,
338"alpha":              IsAlpha,
339"utfletter":          IsUTFLetter,
340"alphanum":           IsAlphanumeric,
341"utfletternum":       IsUTFLetterNumeric,
342"numeric":            IsNumeric,
343"utfnumeric":         IsUTFNumeric,
344"utfdigit":           IsUTFDigit,
345"hexadecimal":        IsHexadecimal,
346"hexcolor":           IsHexcolor,
347"rgbcolor":           IsRGBcolor,
348"lowercase":          IsLowerCase,
349"uppercase":          IsUpperCase,
350"int":                IsInt,
351"float":              IsFloat,
352"null":               IsNull,
353"uuid":               IsUUID,
354"uuidv3":             IsUUIDv3,
355"uuidv4":             IsUUIDv4,
356"uuidv5":             IsUUIDv5,
357"creditcard":         IsCreditCard,
358"isbn10":             IsISBN10,
359"isbn13":             IsISBN13,
360"json":               IsJSON,
361"multibyte":          IsMultibyte,
362"ascii":              IsASCII,
363"printableascii":     IsPrintableASCII,
364"fullwidth":          IsFullWidth,
365"halfwidth":          IsHalfWidth,
366"variablewidth":      IsVariableWidth,
367"base64":             IsBase64,
368"datauri":            IsDataURI,
369"ip":                 IsIP,
370"port":               IsPort,
371"ipv4":               IsIPv4,
372"ipv6":               IsIPv6,
373"dns":                IsDNSName,
374"host":               IsHost,
375"mac":                IsMAC,
376"latitude":           IsLatitude,
377"longitude":          IsLongitude,
378"ssn":                IsSSN,
379"semver":             IsSemver,
380"rfc3339":            IsRFC3339,
381"rfc3339WithoutZone": IsRFC3339WithoutZone,
382"ISO3166Alpha2":      IsISO3166Alpha2,
383"ISO3166Alpha3":      IsISO3166Alpha3,
384```
385Validators with parameters
386
387```go
388"range(min|max)": Range,
389"length(min|max)": ByteLength,
390"runelength(min|max)": RuneLength,
391"stringlength(min|max)": StringLength,
392"matches(pattern)": StringMatches,
393"in(string1|string2|...|stringN)": IsIn,
394"rsapub(keylength)" : IsRsaPub,
395```
396Validators with parameters for any type
397
398```go
399"type(type)": IsType,
400```
401
402And here is small example of usage:
403```go
404type Post struct {
405	Title    string `valid:"alphanum,required"`
406	Message  string `valid:"duck,ascii"`
407	Message2 string `valid:"animal(dog)"`
408	AuthorIP string `valid:"ipv4"`
409	Date     string `valid:"-"`
410}
411post := &Post{
412	Title:   "My Example Post",
413	Message: "duck",
414	Message2: "dog",
415	AuthorIP: "123.234.54.3",
416}
417
418// Add your own struct validation tags
419govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
420	return str == "duck"
421})
422
423// Add your own struct validation tags with parameter
424govalidator.ParamTagMap["animal"] = govalidator.ParamValidator(func(str string, params ...string) bool {
425    species := params[0]
426    return str == species
427})
428govalidator.ParamTagRegexMap["animal"] = regexp.MustCompile("^animal\\((\\w+)\\)$")
429
430result, err := govalidator.ValidateStruct(post)
431if err != nil {
432	println("error: " + err.Error())
433}
434println(result)
435```
436###### ValidateMap [#2](https://github.com/asaskevich/govalidator/pull/338)
437If you want to validate maps, you can use the map to be validated and a validation map that contain the same tags used in ValidateStruct, both maps have to be in the form `map[string]interface{}`
438
439So here is small example of usage:
440```go
441var mapTemplate = map[string]interface{}{
442	"name":"required,alpha",
443	"family":"required,alpha",
444	"email":"required,email",
445	"cell-phone":"numeric",
446	"address":map[string]interface{}{
447		"line1":"required,alphanum",
448		"line2":"alphanum",
449		"postal-code":"numeric",
450	},
451}
452
453var inputMap = map[string]interface{}{
454	"name":"Bob",
455	"family":"Smith",
456	"email":"foo@bar.baz",
457	"address":map[string]interface{}{
458		"line1":"",
459		"line2":"",
460		"postal-code":"",
461	},
462}
463
464result, err := govalidator.ValidateMap(mapTemplate, inputMap)
465if err != nil {
466	println("error: " + err.Error())
467}
468println(result)
469```
470
471###### WhiteList
472```go
473// Remove all characters from string ignoring characters between "a" and "z"
474println(govalidator.WhiteList("a3a43a5a4a3a2a23a4a5a4a3a4", "a-z") == "aaaaaaaaaaaa")
475```
476
477###### Custom validation functions
478Custom validation using your own domain specific validators is also available - here's an example of how to use it:
479```go
480import "github.com/asaskevich/govalidator"
481
482type CustomByteArray [6]byte // custom types are supported and can be validated
483
484type StructWithCustomByteArray struct {
485  ID              CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` // multiple custom validators are possible as well and will be evaluated in sequence
486  Email           string          `valid:"email"`
487  CustomMinLength int             `valid:"-"`
488}
489
490govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, context interface{}) bool {
491  switch v := context.(type) { // you can type switch on the context interface being validated
492  case StructWithCustomByteArray:
493    // you can check and validate against some other field in the context,
494    // return early or not validate against the context at all – your choice
495  case SomeOtherType:
496    // ...
497  default:
498    // expecting some other type? Throw/panic here or continue
499  }
500
501  switch v := i.(type) { // type switch on the struct field being validated
502  case CustomByteArray:
503    for _, e := range v { // this validator checks that the byte array is not empty, i.e. not all zeroes
504      if e != 0 {
505        return true
506      }
507    }
508  }
509  return false
510}))
511govalidator.CustomTypeTagMap.Set("customMinLengthValidator", CustomTypeValidator(func(i interface{}, context interface{}) bool {
512  switch v := context.(type) { // this validates a field against the value in another field, i.e. dependent validation
513  case StructWithCustomByteArray:
514    return len(v.ID) >= v.CustomMinLength
515  }
516  return false
517}))
518```
519
520###### Custom error messages
521Custom error messages are supported via annotations by adding the `~` separator - here's an example of how to use it:
522```go
523type Ticket struct {
524  Id        int64     `json:"id"`
525  FirstName string    `json:"firstname" valid:"required~First name is blank"`
526}
527```
528
529#### Notes
530Documentation is available here: [godoc.org](https://godoc.org/github.com/asaskevich/govalidator).
531Full information about code coverage is also available here: [govalidator on gocover.io](http://gocover.io/github.com/asaskevich/govalidator).
532
533#### Support
534If you do have a contribution to the package, feel free to create a Pull Request or an Issue.
535
536#### What to contribute
537If you don't know what to do, there are some features and functions that need to be done
538
539- [ ] Refactor code
540- [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check
541- [ ] Create actual list of contributors and projects that currently using this package
542- [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues)
543- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions)
544- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new
545- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc
546- [x] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224)
547- [ ] Implement fuzzing testing
548- [ ] Implement some struct/map/array utilities
549- [ ] Implement map/array validation
550- [ ] Implement benchmarking
551- [ ] Implement batch of examples
552- [ ] Look at forks for new features and fixes
553
554#### Advice
555Feel free to create what you want, but keep in mind when you implement new features:
556- Code must be clear and readable, names of variables/constants clearly describes what they are doing
557- Public functions must be documented and described in source file and added to README.md to the list of available functions
558- There are must be unit-tests for any new functions and improvements
559
560## Credits
561### Contributors
562
563This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
564
565#### Special thanks to [contributors](https://github.com/asaskevich/govalidator/graphs/contributors)
566* [Daniel Lohse](https://github.com/annismckenzie)
567* [Attila Oláh](https://github.com/attilaolah)
568* [Daniel Korner](https://github.com/Dadie)
569* [Steven Wilkin](https://github.com/stevenwilkin)
570* [Deiwin Sarjas](https://github.com/deiwin)
571* [Noah Shibley](https://github.com/slugmobile)
572* [Nathan Davies](https://github.com/nathj07)
573* [Matt Sanford](https://github.com/mzsanford)
574* [Simon ccl1115](https://github.com/ccl1115)
575
576<a href="https://github.com/asaskevich/govalidator/graphs/contributors"><img src="https://opencollective.com/govalidator/contributors.svg?width=890" /></a>
577
578
579### Backers
580
581Thank you to all our backers! �� [[Become a backer](https://opencollective.com/govalidator#backer)]
582
583<a href="https://opencollective.com/govalidator#backers" target="_blank"><img src="https://opencollective.com/govalidator/backers.svg?width=890"></a>
584
585
586### Sponsors
587
588Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/govalidator#sponsor)]
589
590<a href="https://opencollective.com/govalidator/sponsor/0/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/0/avatar.svg"></a>
591<a href="https://opencollective.com/govalidator/sponsor/1/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/1/avatar.svg"></a>
592<a href="https://opencollective.com/govalidator/sponsor/2/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/2/avatar.svg"></a>
593<a href="https://opencollective.com/govalidator/sponsor/3/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/3/avatar.svg"></a>
594<a href="https://opencollective.com/govalidator/sponsor/4/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/4/avatar.svg"></a>
595<a href="https://opencollective.com/govalidator/sponsor/5/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/5/avatar.svg"></a>
596<a href="https://opencollective.com/govalidator/sponsor/6/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/6/avatar.svg"></a>
597<a href="https://opencollective.com/govalidator/sponsor/7/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/7/avatar.svg"></a>
598<a href="https://opencollective.com/govalidator/sponsor/8/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/8/avatar.svg"></a>
599<a href="https://opencollective.com/govalidator/sponsor/9/website" target="_blank"><img src="https://opencollective.com/govalidator/sponsor/9/avatar.svg"></a>
600
601
602
603
604## License
605[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_large)