//UTF-16转UTF-8
function utf16ToUtf8(s) {
	if (!s) {
		return
	}
	var i,
		code,
		ret = [],
		len = s.length
	for (i = 0; i < len; i++) {
		code = s.charCodeAt(i)
		if (code > 0x0 && code <= 0x7f) {
			//单字节
			//UTF-16 0000 - 007F
			//UTF-8  0xxxxxxx
			ret.push(s.charAt(i))
		} else if (code >= 0x80 && code <= 0x7ff) {
			//双字节
			//UTF-16 0080 - 07FF
			//UTF-8  110xxxxx 10xxxxxx
			ret.push(
				//110xxxxx
				String.fromCharCode(0xc0 | ((code >> 6) & 0x1f)),
				//10xxxxxx
				String.fromCharCode(0x80 | (code & 0x3f))
			)
		} else if (code >= 0x800 && code <= 0xffff) {
			//三字节
			//UTF-16 0800 - FFFF
			//UTF-8  1110xxxx 10xxxxxx 10xxxxxx
			ret.push(
				//1110xxxx
				String.fromCharCode(0xe0 | ((code >> 12) & 0xf)),
				//10xxxxxx
				String.fromCharCode(0x80 | ((code >> 6) & 0x3f)),
				//10xxxxxx
				String.fromCharCode(0x80 | (code & 0x3f))
			)
		}
	}

	return ret.join('')
}

//UTF-8转UTF-16
function utf8ToUtf16(s) {
	if (!s) {
		return
	}

	var i,
		codes,
		bytes,
		ret = [],
		len = s.length
	for (i = 0; i < len; i++) {
		codes = []
		codes.push(s.charCodeAt(i))
		if (((codes[0] >> 7) & 0xff) == 0x0) {
			//单字节  0xxxxxxx
			ret.push(s.charAt(i))
		} else if (((codes[0] >> 5) & 0xff) == 0x6) {
			//双字节  110xxxxx 10xxxxxx
			codes.push(s.charCodeAt(++i))
			bytes = []
			bytes.push(codes[0] & 0x1f)
			bytes.push(codes[1] & 0x3f)
			ret.push(String.fromCharCode((bytes[0] << 6) | bytes[1]))
		} else if (((codes[0] >> 4) & 0xff) == 0xe) {
			//三字节  1110xxxx 10xxxxxx 10xxxxxx
			codes.push(s.charCodeAt(++i))
			codes.push(s.charCodeAt(++i))
			bytes = []
			bytes.push((codes[0] << 4) | ((codes[1] >> 2) & 0xf))
			bytes.push(((codes[1] & 0x3) << 6) | (codes[2] & 0x3f))
			ret.push(String.fromCharCode((bytes[0] << 8) | bytes[1]))
		}
	}
	return ret.join('')
}

function StringToUint8Array(string) {
	var binLen, buffer, chars, i, _i
	binLen = string.length
	buffer = new ArrayBuffer(binLen)
	chars = new Uint8Array(buffer)
	for (var i = 0; i < binLen; ++i) {
		chars[i] = String.prototype.charCodeAt.call(string, i)
	}
	return buffer
}

function uuid(len, radix = 16) {
	var chars =
		'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
	var uuid = [],
		i
	radix = radix || chars.length
	if (len) {
		for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
	} else {
		var r
		uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
		uuid[14] = '4'
		for (i = 0; i < 36; i++) {
			if (!uuid[i]) {
				r = 0 | (Math.random() * 16)
				uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]
			}
		}
	}

	return uuid.join('')
}

var hexCache = {}
function stringToHex(str) {
	var val = hexCache[str]
	if (val) return val

	for (var i = 0; i < str.length; i++) {
		if (val == '') val = str.charCodeAt(i).toString(16)
		else val += str.charCodeAt(i).toString(16)
	}
	hexCache[str] = val
	return val
}

function getBoolean(str, defaultValue) {
	if (typeof str === 'string') return str.toLocaleLowerCase() === 'true'
	else if (typeof str === 'boolean') return str
	else if (typeof str === 'number') return !!str
	else if (str === undefined) return defaultValue
	else return !!str
}

function getNumber(str, defaultValue) {
	if (typeof str === 'number') return isNaN(str) ? defaultValue : str
	else if (typeof str == 'string')
		return isNaN(Number(str)) ? defaultValue : Number(str)
	else return defaultValue
}

function StringToUint8Array2(str) {
	const encoder = new TextEncoder()
	return encoder.encode(str)
}
