comm.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. package utils
  2. import (
  3. "crypto/md5"
  4. "crypto/rand"
  5. "crypto/sha256"
  6. "encoding/hex"
  7. "encoding/json"
  8. "errors"
  9. "fmt"
  10. "github.com/beego/beego/v2/core/logs"
  11. "io"
  12. "math"
  13. "net/url"
  14. "os"
  15. "regexp"
  16. "strconv"
  17. "strings"
  18. "unicode"
  19. )
  20. // 用户输入组合路径安全校验
  21. func CheckPath(param string) error {
  22. if count := strings.Count(param, "."); count > 0 {
  23. return errors.New("路径中不能包含非法字符“.”")
  24. }
  25. if count := strings.Count(param, "/"); count > 0 {
  26. return errors.New("路径中不能包含非法字符“/”")
  27. }
  28. if count := strings.Count(param, "\\"); count > 0 {
  29. return errors.New("路径中不能包含非法字符“\\”")
  30. }
  31. return nil
  32. }
  33. // 用户输入文件名安全校验
  34. func CheckFilename(param string) error {
  35. if count := strings.Count(param, "."); count > 1 {
  36. return errors.New("文件名中不能超过一个“.”")
  37. }
  38. if count := strings.Count(param, "/"); count > 0 {
  39. return errors.New("文件名中不能包含非法字符“/”")
  40. }
  41. if count := strings.Count(param, "\\"); count > 0 {
  42. return errors.New("文件名中不能包含非法字符“\\”")
  43. }
  44. return nil
  45. }
  46. // 用户文件全路径安全校验
  47. func CheckPathFilename(param string) error {
  48. if count := strings.Count(param, "."); count > 2 {
  49. return errors.New("文件全路径中不能超过两个“.”")
  50. }
  51. if count := strings.Count(param, "/"); count > 5 {
  52. return errors.New("文件全路径中不能包含非法字符“/”")
  53. }
  54. if count := strings.Count(param, "\\"); count > 0 {
  55. return errors.New("文件全路径中不能包含非法字符“\\”")
  56. }
  57. return nil
  58. }
  59. // 提取url中的路径
  60. func GetUrlPath(rawURL string) string {
  61. parsedURL, err := url.Parse(rawURL)
  62. if err != nil {
  63. logs.Error("url parse error: %v", err)
  64. return ""
  65. }
  66. return parsedURL.Path
  67. }
  68. // 字符串替换非法字符
  69. func ReplaceUserInput(s string) string {
  70. newStringInput := strings.NewReplacer("\n", " ", "\r", " ")
  71. return newStringInput.Replace(s)
  72. }
  73. // 字符包含非法字符
  74. func ContainsIllegal(target string) bool {
  75. var str_array [3]string = [3]string{"/", "./", "\\"}
  76. for _, element := range str_array {
  77. if strings.Contains(target, element) {
  78. return true
  79. }
  80. }
  81. return false
  82. }
  83. // 文件md5计算
  84. func FileSign(filePath string, sign string) (string, error) {
  85. check_err := CheckPathFilename(filePath)
  86. if check_err != nil {
  87. return "", check_err
  88. }
  89. file, err := os.Open(filePath)
  90. if err != nil {
  91. return "", err
  92. }
  93. if sign == "MD5" {
  94. hash := md5.New()
  95. _, _ = io.Copy(hash, file)
  96. return hex.EncodeToString(hash.Sum(nil)), nil
  97. } else {
  98. hash := sha256.New()
  99. _, _ = io.Copy(hash, file)
  100. return hex.EncodeToString(hash.Sum(nil)), nil
  101. }
  102. }
  103. func GetFileSize(filePath string) (int64, error) {
  104. check_err := CheckPathFilename(filePath)
  105. if check_err != nil {
  106. return 0, check_err
  107. }
  108. fi, err := os.Stat(filePath)
  109. if err != nil {
  110. return 0, err
  111. }
  112. return fi.Size(), nil
  113. }
  114. // GenerateAppKey 生成指定字节长度的随机字符串
  115. func GenerateAppKey(length int) string {
  116. b := make([]byte, length)
  117. _, err := rand.Read(b)
  118. if err != nil {
  119. panic(err)
  120. }
  121. return hex.EncodeToString(b)
  122. }
  123. // 驼峰转_
  124. func CamelToSnake(s string) string {
  125. var result []rune
  126. for i, r := range s {
  127. if i > 0 && unicode.IsUpper(r) {
  128. result = append(result, '_')
  129. }
  130. result = append(result, unicode.ToLower(r))
  131. }
  132. return string(result)
  133. }
  134. func WordsToSnake(s string) string {
  135. return strings.Replace(s, " ", "_", -1)
  136. }
  137. func ToInt(value interface{}) int {
  138. var key int
  139. if value == nil {
  140. return key
  141. }
  142. switch value.(type) {
  143. case float64:
  144. key = int(value.(float64))
  145. case float32:
  146. key = int(value.(float32))
  147. case int:
  148. key = int(value.(int))
  149. case uint:
  150. key = int(value.(uint))
  151. case int8:
  152. key = int(value.(int8))
  153. case uint8:
  154. key = int(value.(uint8))
  155. case int16:
  156. key = int(value.(int16))
  157. case uint16:
  158. key = int(value.(uint16))
  159. case int32:
  160. key = int(value.(int32))
  161. case uint32:
  162. key = int(value.(uint32))
  163. case int64:
  164. key = int(value.(int64))
  165. case uint64:
  166. key = int(value.(uint64))
  167. case string:
  168. key, _ = strconv.Atoi(value.(string))
  169. case []byte:
  170. key, _ = strconv.Atoi(string(value.([]byte)))
  171. default:
  172. newValue, _ := json.Marshal(value)
  173. key, _ = strconv.Atoi(string(newValue))
  174. }
  175. return key
  176. }
  177. func ToFloat64(value interface{}) float64 {
  178. var key float64
  179. if value == nil {
  180. return key
  181. }
  182. switch value.(type) {
  183. case float64:
  184. key = value.(float64)
  185. case float32:
  186. key = float64(value.(float32))
  187. case int:
  188. key = float64(value.(int))
  189. case uint:
  190. key = float64(value.(uint))
  191. case int8:
  192. key = float64(value.(int8))
  193. case uint8:
  194. key = float64(value.(uint8))
  195. case int16:
  196. key = float64(value.(int16))
  197. case uint16:
  198. key = float64(value.(uint16))
  199. case int32:
  200. key = float64(value.(int32))
  201. case uint32:
  202. key = float64(value.(uint32))
  203. case int64:
  204. key = float64(value.(int64))
  205. case uint64:
  206. key = float64(value.(uint64))
  207. case string:
  208. key_float64, _ := strconv.ParseFloat(value.(string), 32/64)
  209. key = key_float64
  210. case []byte:
  211. key_float64, _ := strconv.ParseFloat(string(value.([]byte)), 32/64)
  212. key = key_float64
  213. default:
  214. newValue, _ := json.Marshal(value)
  215. key_float64, _ := strconv.ParseFloat(string(newValue), 32/64)
  216. key = key_float64
  217. }
  218. key_float64, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", key), 32/64)
  219. return key_float64
  220. }
  221. // IsChineseOnly 判断字符串是否只包含中文字符
  222. func IsChineseOnly(s string) bool {
  223. chineseRegexp := regexp.MustCompile("^[\\p{Han}]+$")
  224. return chineseRegexp.MatchString(s)
  225. }
  226. // 将数字转换为中文大写形式
  227. func AmountConvert(p_money float64, p_round bool) string {
  228. var NumberUpper = []string{"壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "零"}
  229. var Unit = []string{"分", "角", "圆", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"}
  230. var regex = [][]string{
  231. {"零拾", "零"}, {"零佰", "零"}, {"零仟", "零"}, {"零零零", "零"}, {"零零", "零"},
  232. {"零角零分", "整"}, {"零分", "整"}, {"零角", "零"}, {"零亿零万零元", "亿元"},
  233. {"亿零万零元", "亿元"}, {"零亿零万", "亿"}, {"零万零元", "万元"}, {"万零元", "万元"},
  234. {"零亿", "亿"}, {"零万", "万"}, {"拾零圆", "拾元"}, {"零圆", "元"}, {"零零", "零"}}
  235. str, DigitUpper, Unit_Len, round := "", "", 0, 0
  236. if p_money == 0 {
  237. return "零"
  238. }
  239. if p_money < 0 {
  240. str = "负"
  241. p_money = math.Abs(p_money)
  242. }
  243. if p_round {
  244. round = 2
  245. } else {
  246. round = 1
  247. }
  248. Digit_byte := []byte(strconv.FormatFloat(p_money, 'f', round+1, 64)) //注意币种四舍五入
  249. Unit_Len = len(Digit_byte) - round
  250. for _, v := range Digit_byte {
  251. if Unit_Len >= 1 && v != 46 {
  252. s, _ := strconv.ParseInt(string(v), 10, 0)
  253. if s != 0 {
  254. DigitUpper = NumberUpper[s-1]
  255. } else {
  256. DigitUpper = "零"
  257. }
  258. str = str + DigitUpper + Unit[Unit_Len-1]
  259. Unit_Len = Unit_Len - 1
  260. }
  261. }
  262. for i, _ := range regex {
  263. reg := regexp.MustCompile(regex[i][0])
  264. str = reg.ReplaceAllString(str, regex[i][1])
  265. }
  266. if string(str[0:3]) == "元" {
  267. str = str[3:len(str)]
  268. }
  269. if string(str[0:3]) == "零" {
  270. str = str[3:len(str)]
  271. }
  272. if strings.Contains(str, "角") {
  273. str = strings.Replace(str, "整", "", 1)
  274. }
  275. return str
  276. }