cshenfu
2023-05-17 ccda24599f10f91a4a58f577e674c8e342c8c7a1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const crypto = require('crypto')
const {
  isPlainObject
} = require('../../../common/utils')
 
// 退款通知解密key=md5(key)
function decryptData (encryptedData, key, iv = '') {
  // 解密
  const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv)
  // 设置自动 padding 为 true,删除填充补位
  decipher.setAutoPadding(true)
  let decoded = decipher.update(encryptedData, 'base64', 'utf8')
  decoded += decipher.final('utf8')
  return decoded
}
 
function md5 (str, encoding = 'utf8') {
  return crypto
    .createHash('md5')
    .update(str, encoding)
    .digest('hex')
}
 
function sha256 (str, key, encoding = 'utf8') {
  return crypto
    .createHmac('sha256', key)
    .update(str, encoding)
    .digest('hex')
}
 
function getSignStr (obj) {
  return Object.keys(obj)
    .filter(key => key !== 'sign' && obj[key] !== undefined && obj[key] !== '')
    .sort()
    .map(key => key + '=' + obj[key])
    .join('&')
}
 
function getNonceStr (length = 16) {
  let str = ''
  while (str.length < length) {
    str += Math.random().toString(32).substring(2)
  }
  return str.substring(0, length)
}
 
// 简易版Object转XML,只可在微信支付时使用,不支持嵌套
function buildXML (obj, rootName = 'xml') {
  const content = Object.keys(obj).map(item => {
    if (isPlainObject(obj[item])) {
      return `<${item}><![CDATA[${JSON.stringify(obj[item])}]]></${item}>`
    } else {
      return `<${item}><![CDATA[${obj[item]}]]></${item}>`
    }
  })
  return `<${rootName}>${content.join('')}</${rootName}>`
}
 
function isXML (str) {
  const reg = /^(<\?xml.*\?>)?(\r?\n)*<xml>(.|\r?\n)*<\/xml>$/i
  return reg.test(str.trim())
};
 
// 简易版XML转Object,只可在微信支付时使用,不支持嵌套
function parseXML (xml) {
  const xmlReg = /<(?:xml|root).*?>([\s|\S]*)<\/(?:xml|root)>/
  const str = xmlReg.exec(xml)[1]
  const obj = {}
  const nodeReg = /<(.*?)>(?:<!\[CDATA\[){0,1}(.*?)(?:\]\]>){0,1}<\/.*?>/g
  let matches = null
  // eslint-disable-next-line no-cond-assign
  while ((matches = nodeReg.exec(str))) {
    obj[matches[1]] = matches[2]
  }
  return obj
}
 
module.exports = {
  decryptData,
  md5,
  sha256,
  getSignStr,
  getNonceStr,
  buildXML,
  parseXML,
  isXML
}