comm.go 8.2 KB

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