1package faker
2
3import (
4 "fmt"
5 "net"
6 "reflect"
7 "strings"
8
9 "github.com/go-faker/faker/v4/pkg/options"
10)
11
12var tld = []string{"com", "biz", "info", "net", "org", "ru", "edu", "top"}
13var urlFormats = []string{
14 "http://www.%s/",
15 "https://www.%s/",
16 "http://%s/",
17 "https://%s/",
18 "http://www.%s/%s",
19 "https://www.%s/%s",
20 "http://%s/%s",
21 "https://%s/%s",
22 "http://%s/%s.html",
23 "https://%s/%s.html",
24 "http://%s/%s.php",
25 "https://%s/%s.php",
26 "http://%s/%s.jpg",
27 "https://%s/%s.jpg",
28 "http://%s/%s.webp",
29 "https://%s/%s.webp",
30 "http://%s/%s.js",
31 "https://%s/%s.js",
32 "http://%s/%s.css",
33 "https://%s/%s.css",
34 "http://%s/%s.svg",
35 "https://%s/%s.svg",
36}
37
38// GetNetworker returns a new Networker interface of Internet
39func GetNetworker(opts ...options.OptionFunc) Networker {
40 opt := options.BuildOptions(opts)
41 internet := &Internet{
42 fakerOption: *opt,
43 }
44 return internet
45}
46
47// Networker is logical layer for Internet
48type Networker interface {
49 Email(v reflect.Value) (interface{}, error)
50 MacAddress(v reflect.Value) (interface{}, error)
51 DomainName(v reflect.Value) (interface{}, error)
52 URL(v reflect.Value) (interface{}, error)
53 UserName(v reflect.Value) (interface{}, error)
54 IPv4(v reflect.Value) (interface{}, error)
55 IPv6(v reflect.Value) (interface{}, error)
56 Password(v reflect.Value) (interface{}, error)
57 Jwt(v reflect.Value) (interface{}, error)
58}
59
60// Internet struct
61type Internet struct {
62 fakerOption options.Options
63}
64
65func (internet Internet) email() (string, error) {
66 var err error
67 var emailName, emailDomain string
68 if emailName, err = randomString(7, internet.fakerOption); err != nil {
69 return "", err
70 }
71
72 if internet.fakerOption.CustomDomain != nil {
73 emailDomain = *internet.fakerOption.CustomDomain
74 } else {
75 randDomain, err := randomString(7, internet.fakerOption)
76 if err != nil {
77 return "", err
78 }
79
80 emailDomain = randDomain + "." + randomElementFromSliceString(tld)
81 }
82
83 return (emailName + "@" + emailDomain), nil
84}
85
86// Email generates random email id
87func (internet Internet) Email(v reflect.Value) (interface{}, error) {
88 return internet.email()
89}
90
91// Email get email randomly in string
92func Email(opts ...options.OptionFunc) string {
93 return singleFakeData(EmailTag, func() interface{} {
94 opt := options.BuildOptions(opts)
95 i := Internet{fakerOption: *opt}
96 r, err := i.email()
97 if err != nil {
98 panic(err.Error())
99 }
100 return r
101 }, opts...).(string)
102}
103
104func (internet Internet) macAddress() string {
105 ip := make([]byte, 6)
106 for i := 0; i < 6; i++ {
107 ip[i] = byte(rand.Intn(256))
108 }
109 return net.HardwareAddr(ip).String()
110}
111
112// MacAddress generates random MacAddress
113func (internet Internet) MacAddress(v reflect.Value) (interface{}, error) {
114 return internet.macAddress(), nil
115}
116
117// MacAddress get mac address randomly in string
118func MacAddress(opts ...options.OptionFunc) string {
119 return singleFakeData(MacAddressTag, func() interface{} {
120 opt := options.BuildOptions(opts)
121 i := Internet{fakerOption: *opt}
122 return i.macAddress()
123 }, opts...).(string)
124}
125
126func (internet Internet) domainName() (string, error) {
127 domainPart, err := randomString(7, internet.fakerOption)
128 if err != nil {
129 return "", err
130 }
131 return (strings.ToLower(domainPart) + "." + randomElementFromSliceString(tld)), nil
132}
133
134// DomainName generates random domain name
135func (internet Internet) DomainName(v reflect.Value) (interface{}, error) {
136 return internet.domainName()
137}
138
139// DomainName get email domain name in string
140func DomainName(opts ...options.OptionFunc) string {
141 return singleFakeData(DomainNameTag, func() interface{} {
142 opt := options.BuildOptions(opts)
143 i := Internet{fakerOption: *opt}
144 d, err := i.domainName()
145 if err != nil {
146 panic(err.Error())
147 }
148 return d
149 }, opts...).(string)
150}
151
152func (internet Internet) url() (string, error) {
153 format := randomElementFromSliceString(urlFormats)
154 countVerbs := strings.Count(format, "%s")
155 d, err := internet.domainName()
156 if err != nil {
157 return "", nil
158 }
159 if countVerbs == 1 {
160 return fmt.Sprintf(format, d), nil
161 }
162 u, err := internet.username()
163 if err != nil {
164 return "", err
165 }
166 return fmt.Sprintf(format, d, u), nil
167}
168
169// URL generates random URL standardized in urlFormats const
170func (internet Internet) URL(v reflect.Value) (interface{}, error) {
171 return internet.url()
172}
173
174// URL get Url randomly in string
175func URL(opts ...options.OptionFunc) string {
176 return singleFakeData(URLTag, func() interface{} {
177 opt := options.BuildOptions(opts)
178 i := Internet{fakerOption: *opt}
179 u, err := i.url()
180 if err != nil {
181 panic(err.Error())
182 }
183 return u
184 }, opts...).(string)
185}
186
187func (internet Internet) username() (string, error) {
188 return randomString(7, internet.fakerOption)
189}
190
191// UserName generates random username
192func (internet Internet) UserName(v reflect.Value) (interface{}, error) {
193 return internet.username()
194}
195
196// Username get username randomly in string
197func Username(opts ...options.OptionFunc) string {
198 return singleFakeData(UserNameTag, func() interface{} {
199 opt := options.BuildOptions(opts)
200 i := Internet{fakerOption: *opt}
201 u, err := i.username()
202 if err != nil {
203 panic(err.Error())
204 }
205 return u
206 }, opts...).(string)
207}
208
209func (internet Internet) ipv4() string {
210 size := 4
211 ip := make([]byte, size)
212 for i := 0; i < size; i++ {
213 ip[i] = byte(rand.Intn(256))
214 }
215 return net.IP(ip).To4().String()
216}
217
218// IPv4 generates random IPv4 address
219func (internet Internet) IPv4(v reflect.Value) (interface{}, error) {
220 return internet.ipv4(), nil
221}
222
223// IPv4 get IPv4 randomly in string
224func IPv4(opts ...options.OptionFunc) string {
225 return singleFakeData(IPV4Tag, func() interface{} {
226 opt := options.BuildOptions(opts)
227 i := Internet{fakerOption: *opt}
228 return i.ipv4()
229 }, opts...).(string)
230}
231
232func (internet Internet) ipv6() string {
233 size := 16
234 ip := make([]byte, size)
235 for i := 0; i < size; i++ {
236 ip[i] = byte(rand.Intn(256))
237 }
238 return net.IP(ip).To16().String()
239}
240
241// IPv6 generates random IPv6 address
242func (internet Internet) IPv6(v reflect.Value) (interface{}, error) {
243 return internet.ipv6(), nil
244}
245
246// IPv6 get IPv6 randomly in string
247func IPv6(opts ...options.OptionFunc) string {
248 return singleFakeData(IPV6Tag, func() interface{} {
249 opt := options.BuildOptions(opts)
250 i := Internet{fakerOption: *opt}
251 return i.ipv6()
252 }, opts...).(string)
253}
254
255func (internet Internet) password() (string, error) {
256 return randomString(50, internet.fakerOption)
257}
258
259// Password returns a hashed password
260func (internet Internet) Password(v reflect.Value) (interface{}, error) {
261 return internet.password()
262}
263
264// Password get password randomly in string
265func Password(opts ...options.OptionFunc) string {
266 return singleFakeData(PASSWORD, func() interface{} {
267 opt := options.BuildOptions(opts)
268 i := Internet{fakerOption: *opt}
269 p, err := i.password()
270 if err != nil {
271 panic(err.Error())
272 }
273 return p
274 }, opts...).(string)
275}
276
277func (internet Internet) jwt() (string, error) {
278 element, err := randomString(40, internet.fakerOption)
279 sl := element[:]
280 if err != nil {
281 return "", err
282 }
283 return strings.Join([]string{sl, sl, sl}, "."), nil
284}
285
286// Jwt returns a jwt-like random string in xxxx.yyyy.zzzz style
287func (internet Internet) Jwt(v reflect.Value) (interface{}, error) {
288 return internet.jwt()
289}
290
291// Jwt get jwt-like string
292func Jwt(opts ...options.OptionFunc) string {
293 return singleFakeData(JWT, func() interface{} {
294 opt := options.BuildOptions(opts)
295 i := Internet{fakerOption: *opt}
296 p, err := i.jwt()
297 if err != nil {
298 panic(err.Error())
299 }
300 return p
301 }, opts...).(string)
302}