__init__.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. # coding=utf-8
  2. from __future__ import unicode_literals
  3. import hashlib
  4. import string
  5. import uuid
  6. import os
  7. import sys
  8. from .. import BaseProvider
  9. class Provider(BaseProvider):
  10. # Locales supported by Linux Mint from `/usr/share/i18n/SUPPORTED`
  11. language_locale_codes = {
  12. 'aa': ('DJ', 'ER', 'ET'), 'af': ('ZA',), 'ak': ('GH',), 'am': ('ET',),
  13. 'an': ('ES',), 'apn': ('IN',),
  14. 'ar': ('AE', 'BH', 'DJ', 'DZ', 'EG', 'EH', 'ER', 'IL', 'IN',
  15. 'IQ', 'JO', 'KM', 'KW', 'LB', 'LY', 'MA', 'MR', 'OM',
  16. 'PS', 'QA', 'SA', 'SD', 'SO', 'SS', 'SY', 'TD', 'TN',
  17. 'YE'),
  18. 'as': ('IN',), 'ast': ('ES',), 'ayc': ('PE',), 'az': ('AZ', 'IN'),
  19. 'be': ('BY',), 'bem': ('ZM',), 'ber': ('DZ', 'MA'), 'bg': ('BG',),
  20. 'bhb': ('IN',), 'bho': ('IN',), 'bn': ('BD', 'IN'), 'bo': ('CN', 'IN'),
  21. 'br': ('FR',), 'brx': ('IN',), 'bs': ('BA',), 'byn': ('ER',),
  22. 'ca': ('AD', 'ES', 'FR', 'IT'), 'ce': ('RU',), 'ckb': ('IQ',),
  23. 'cmn': ('TW',), 'crh': ('UA',), 'cs': ('CZ',), 'csb': ('PL',),
  24. 'cv': ('RU',), 'cy': ('GB',), 'da': ('DK',),
  25. 'de': ('AT', 'BE', 'CH', 'DE', 'LI', 'LU'), 'doi': ('IN',),
  26. 'dv': ('MV',), 'dz': ('BT',), 'el': ('GR', 'CY'),
  27. 'en': ('AG', 'AU', 'BW', 'CA', 'DK', 'GB', 'HK', 'IE', 'IN', 'NG',
  28. 'NZ', 'PH', 'SG', 'US', 'ZA', 'ZM', 'ZW'),
  29. 'eo': ('US',),
  30. 'es': ('AR', 'BO', 'CL', 'CO', 'CR', 'CU', 'DO', 'EC', 'ES', 'GT',
  31. 'HN', 'MX', 'NI', 'PA', 'PE', 'PR', 'PY', 'SV', 'US', 'UY', 'VE'
  32. ), 'et': ('EE',), 'eu': ('ES', 'FR'), 'fa': ('IR',),
  33. 'ff': ('SN',), 'fi': ('FI',), 'fil': ('PH',), 'fo': ('FO',),
  34. 'fr': ('CA', 'CH', 'FR', 'LU'), 'fur': ('IT',), 'fy': ('NL', 'DE'),
  35. 'ga': ('IE',), 'gd': ('GB',), 'gez': ('ER', 'ET'), 'gl': ('ES',),
  36. 'gu': ('IN',), 'gv': ('GB',), 'ha': ('NG',), 'hak': ('TW',),
  37. 'he': ('IL',), 'hi': ('IN',), 'hne': ('IN',), 'hr': ('HR',),
  38. 'hsb': ('DE',), 'ht': ('HT',), 'hu': ('HU',), 'hy': ('AM',),
  39. 'ia': ('FR',), 'id': ('ID',), 'ig': ('NG',), 'ik': ('CA',),
  40. 'is': ('IS',), 'it': ('CH', 'IT'), 'iu': ('CA',), 'iw': ('IL',),
  41. 'ja': ('JP',), 'ka': ('GE',), 'kk': ('KZ',), 'kl': ('GL',),
  42. 'km': ('KH',), 'kn': ('IN',), 'ko': ('KR',), 'kok': ('IN',),
  43. 'ks': ('IN',), 'ku': ('TR',), 'kw': ('GB',), 'ky': ('KG',),
  44. 'lb': ('LU',), 'lg': ('UG',), 'li': ('BE', 'NL'), 'lij': ('IT',),
  45. 'ln': ('CD',), 'lo': ('LA',), 'lt': ('LT',), 'lv': ('LV',),
  46. 'lzh': ('TW',), 'mag': ('IN',), 'mai': ('IN',), 'mg': ('MG',),
  47. 'mhr': ('RU',), 'mi': ('NZ',), 'mk': ('MK',), 'ml': ('IN',),
  48. 'mn': ('MN',), 'mni': ('IN',), 'mr': ('IN',), 'ms': ('MY',),
  49. 'mt': ('MT',), 'my': ('MM',), 'nan': ('TW',), 'nb': ('NO',),
  50. 'nds': ('DE', 'NL'), 'ne': ('NP',), 'nhn': ('MX',),
  51. 'niu': ('NU', 'NZ'), 'nl': ('AW', 'BE', 'NL'), 'nn': ('NO',),
  52. 'nr': ('ZA',), 'nso': ('ZA',), 'oc': ('FR',), 'om': ('ET', 'KE'),
  53. 'or': ('IN',), 'os': ('RU',), 'pa': ('IN', 'PK'),
  54. 'pap': ('AN', 'AW', 'CW'), 'pl': ('PL',), 'ps': ('AF',),
  55. 'pt': ('BR', 'PT'), 'quz': ('PE',), 'raj': ('IN',), 'ro': ('RO',),
  56. 'ru': ('RU', 'UA'), 'rw': ('RW',), 'sa': ('IN',), 'sat': ('IN',),
  57. 'sc': ('IT',), 'sd': ('IN', 'PK'), 'se': ('NO',), 'shs': ('CA',),
  58. 'si': ('LK',), 'sid': ('ET',), 'sk': ('SK',), 'sl': ('SI',),
  59. 'so': ('DJ', 'ET', 'KE', 'SO'), 'sq': ('AL', 'ML'), 'sr': ('ME', 'RS'),
  60. 'ss': ('ZA',), 'st': ('ZA',), 'sv': ('FI', 'SE'), 'sw': ('KE', 'TZ'),
  61. 'szl': ('PL',), 'ta': ('IN', 'LK'), 'tcy': ('IN',), 'te': ('IN',),
  62. 'tg': ('TJ',), 'th': ('TH',), 'the': ('NP',), 'ti': ('ER', 'ET'),
  63. 'tig': ('ER',), 'tk': ('TM',), 'tl': ('PH',), 'tn': ('ZA',),
  64. 'tr': ('CY', 'TR'), 'ts': ('ZA',), 'tt': ('RU',), 'ug': ('CN',),
  65. 'uk': ('UA',), 'unm': ('US',), 'ur': ('IN', 'PK'), 'uz': ('UZ',),
  66. 've': ('ZA',), 'vi': ('VN',), 'wa': ('BE',), 'wae': ('CH',),
  67. 'wal': ('ET',), 'wo': ('SN',), 'xh': ('ZA',), 'yi': ('US',),
  68. 'yo': ('NG',), 'yue': ('HK',), 'zh': ('CN', 'HK', 'SG', 'TW'),
  69. 'zu': ('ZA',)
  70. }
  71. def boolean(self, chance_of_getting_true=50):
  72. return self.generator.random.randint(1, 100) <= chance_of_getting_true
  73. def null_boolean(self):
  74. return {
  75. 0: None,
  76. 1: True,
  77. -1: False
  78. }[self.generator.random.randint(-1, 1)]
  79. def binary(self, length=(1 * 1024 * 1024)):
  80. """ Returns random binary blob.
  81. Default blob size is 1 Mb.
  82. """
  83. blob = [self.generator.random.randrange(256) for _ in range(length)]
  84. return bytes(blob) if sys.version_info[0] >= 3 else bytearray(blob)
  85. def md5(self, raw_output=False):
  86. """
  87. Calculates the md5 hash of a given string
  88. :example 'cfcd208495d565ef66e7dff9f98764da'
  89. """
  90. res = hashlib.md5(str(self.generator.random.random()).encode('utf-8'))
  91. if raw_output:
  92. return res.digest()
  93. return res.hexdigest()
  94. def sha1(self, raw_output=False):
  95. """
  96. Calculates the sha1 hash of a given string
  97. :example 'b5d86317c2a144cd04d0d7c03b2b02666fafadf2'
  98. """
  99. res = hashlib.sha1(str(self.generator.random.random()).encode('utf-8'))
  100. if raw_output:
  101. return res.digest()
  102. return res.hexdigest()
  103. def sha256(self, raw_output=False):
  104. """
  105. Calculates the sha256 hash of a given string
  106. :example '85086017559ccc40638fcde2fecaf295e0de7ca51b7517b6aebeaaf75b4d4654'
  107. """
  108. res = hashlib.sha256(
  109. str(self.generator.random.random()).encode('utf-8'))
  110. if raw_output:
  111. return res.digest()
  112. return res.hexdigest()
  113. def locale(self):
  114. language_code = self.language_code()
  115. return language_code + '_' + self.random_element(
  116. Provider.language_locale_codes[language_code]
  117. )
  118. def language_code(self):
  119. return self.random_element(Provider.language_locale_codes.keys())
  120. def uuid4(self):
  121. """
  122. Generates a random UUID4 string.
  123. """
  124. # Based on http://stackoverflow.com/q/41186818
  125. return str(uuid.UUID(int=self.generator.random.getrandbits(128)))
  126. def password(
  127. self,
  128. length=10,
  129. special_chars=True,
  130. digits=True,
  131. upper_case=True,
  132. lower_case=True):
  133. """
  134. Generates a random password.
  135. @param length: Integer. Length of a password
  136. @param special_chars: Boolean. Whether to use special characters !@#$%^&*()_+
  137. @param digits: Boolean. Whether to use digits
  138. @param upper_case: Boolean. Whether to use upper letters
  139. @param lower_case: Boolean. Whether to use lower letters
  140. @return: String. Random password
  141. """
  142. choices = ""
  143. required_tokens = []
  144. if special_chars:
  145. required_tokens.append(
  146. self.generator.random.choice("!@#$%^&*()_+"))
  147. choices += "!@#$%^&*()_+"
  148. if digits:
  149. required_tokens.append(self.generator.random.choice(string.digits))
  150. choices += string.digits
  151. if upper_case:
  152. required_tokens.append(
  153. self.generator.random.choice(string.ascii_uppercase))
  154. choices += string.ascii_uppercase
  155. if lower_case:
  156. required_tokens.append(
  157. self.generator.random.choice(string.ascii_lowercase))
  158. choices += string.ascii_lowercase
  159. assert len(
  160. required_tokens) <= length, "Required length is shorter than required characters"
  161. # Generate a first version of the password
  162. chars = self.random_choices(choices, length=length)
  163. # Pick some unique locations
  164. random_indexes = set()
  165. while len(random_indexes) < len(required_tokens):
  166. random_indexes.add(
  167. self.generator.random.randint(0, len(chars) - 1))
  168. # Replace them with the required characters
  169. for i, index in enumerate(random_indexes):
  170. chars[index] = required_tokens[i]
  171. return ''.join(chars)