This commit is contained in:
houjunxiang
2025-10-09 18:19:55 +08:00
parent f2ffc65094
commit 386f1e7466
1553 changed files with 284685 additions and 32820 deletions

235
nx/api/assayTask.js Normal file
View File

@@ -0,0 +1,235 @@
import request from '@/nx/request'
const taskDetailPrefix = '/qms/bus/qmsBusAssayTaskDetail'
const taskPrefix = '/qms/bus/qmsBusAssayTask'
// 获取任务明细
const getAssayTaskDetailListByTaskNo = params => {
return request({
url: taskDetailPrefix + '/detailListByTaskNo',
method: 'GET',
params: {
...params
},
custom: {
isTransformResponse: true
}
})
}
//发起终止样品申请(退回样品)
const createRollbackApply = data => {
return request({
url: '/qms/bus/qmsBusAssayTask/createRollbackApply',
method: 'POST',
data: data,
custom: {
showSuccess: true
}
})
}
const getAssayTaskDetailById = params => {
return request({
url: taskDetailPrefix + '/queryById',
method: 'GET',
params: {
...params
}
})
}
//收样
const execReceiveSample = data => {
return request({
url: '/qms/bus/qmsBusAssayTask/receiveSample',
method: 'POST',
data: data,
custom: {
showSuccess: true
}
})
}
//送样
const execSendSample = data => {
return request({
url: '/qms/bus/qmsBusAssayTask/sendSample',
method: 'POST',
data: data
})
}
// 获取任务明细字段
const queryFieldsByTaskDetail = params => {
return request({
url: '/qms/config/qmsConAssayTaskDetailField/queryFieldsByTaskDetail',
method: 'GET',
params: {
...params
},
custom: {
isTransformResponse: true
}
})
}
// 获取任务明细字段
const queryHeadFieldsByTaskNo = params => {
return request({
url: '/qms/config/qmsConAssayTaskHead/queryHeadFieldsByTaskNo',
method: 'GET',
params: {
...params
}
})
}
// 获取任务抬头值
const queryHeadValueByTaskNo = params => {
return request({
url: '/qms/bus/qmsBusAssayTaskHead/queryHeadValueByTaskNo',
method: 'GET',
params: {
...params
},
custom: {
showError: false,
isTransformResponse: true
}
})
}
// 保存任务抬头值
const saveHeadValue = params => {
return request({
url: '/qms/bus/qmsBusAssayTaskHead/saveOrUpdate',
method: 'POST',
data: params,
custom: {
showSuccess: true
}
})
}
// 保存任务明细
const saveDetailValue = params => {
return request({
url: '/qms/bus/qmsBusAssayTask/saveTaskDetail',
method: 'POST',
data: params,
custom: {
showSuccess: true
}
})
}
// 提交任务明细-停用
const submitTaskDetail = params => {
return request({
url: '/qms/bus/qmsBusAssayTask/submitTaskDetail',
method: 'POST',
params: {
...params
}
})
}
const submitTask = params => {
return request({
url: '/qms/bus/qmsBusAssayTask/submitTaskByTaskNo',
method: 'POST',
params: {
...params
},
custom: {
showSuccess: true
}
})
}
// 撤销提交任务明细
const redoAssayTaskDetail = params => {
return request({
url: '/qms/bus/qmsBusAssayTask/redoAssayTaskDetail',
method: 'POST',
params: {
...params
}
})
}
// 保存抬头时更新字段到明细
const saveHeadValueToDetail = params => {
return request({
url: '/qms/bus/qmsBusAssayTaskHead/saveHeadValueToDetail',
method: 'POST',
data: params,
custom: {
showSuccess: true
}
})
}
//数据上报
const reportAssayTask = id => {
return request({
url: taskPrefix + '/reportAssayTask',
method: 'POST',
params: {
id
},
custom: {
showSuccess: true,
isTransformResponse: true
}
})
}
const rollbackAssayTask = id => {
return request({
url: taskPrefix + '/rollbackAssayTask',
method: 'POST',
params: {
id
}
})
}
/*
* 查询回收率配置*/
const queryConRecoveryRateList = param => {
return request({
url: '/qms/config/recoveryRate/list',
method: 'GET',
params: param
})
}
/*
* 查询样品流程节点
* */
const queryQmsDicSampleProcessCodeList = () => {
return request({
url: '/qms/dic/qmsDicSampleProcessCode/list?pageSize=9999',
method: 'GET'
})
}
export default {
getAssayTaskDetailListByTaskNo,
getAssayTaskDetailById,
queryFieldsByTaskDetail,
queryHeadFieldsByTaskNo,
queryHeadValueByTaskNo,
saveHeadValue,
saveDetailValue,
reportAssayTask,
saveHeadValueToDetail,
redoAssayTaskDetail,
queryConRecoveryRateList,
execReceiveSample,
execSendSample,
createRollbackApply,
rollbackAssayTask,
submitTask,
queryQmsDicSampleProcessCodeList
}

141
nx/api/auncel.js Normal file
View File

@@ -0,0 +1,141 @@
import request from '@/nx/request'
const taskPrefix = '/qms/bus/qmsBusAssayTask'
const taskDetailPrefix = '/qms/bus/qmsBusAssayTaskDetail'
// 获取任务
const getAssayTaskList = params => {
return request({
url: taskPrefix + '/listTaskForPAD',
method: 'GET',
params: {
...params
}
})
}
// 天平称重
const auncelWeigh = params => {
return request({
url: taskDetailPrefix + '/saveWeight',
method: 'POST',
data: params
})
}
//撤销称重
const auncelWeighRevoke = id => {
return request({
url: taskDetailPrefix + '/revokeWeight',
method: 'POST',
params: {
id
}
})
}
// 批量称重提交
const weighBatchSubmitByTaskNo = taskNo => {
return request({
url: taskDetailPrefix + '/submitWeightTaskByTaskNo',
method: 'POST',
params: {
taskNo
}
})
}
// 批量称重提交
const weighBatchSubmitByIds = ids => {
return request({
url: taskDetailPrefix + '/submitWeightTaskByIds',
method: 'POST',
params: {
ids
}
})
}
// 任务单复核
const assayTaskReview = id => {
return request({
url: taskPrefix + '/review',
method: 'POST',
params: {
id
}
})
}
// 任务单及样品复核
const reviewWeightTaskByTaskIdAndSampleIds = (taskId, sampleIds) => {
return request({
url: taskDetailPrefix + '/reviewWeightTaskByTaskIdAndSampleIds',
method: 'POST',
params: {
taskId,
sampleIds
}
})
}
// 复核
const assayTaskDetailReview = id => {
return request({
url: taskDetailPrefix + '/review',
method: 'POST',
params: {
id
}
})
}
// 恢复
const assayTaskDetailRecovery = id => {
return request({
url: taskDetailPrefix + '/recovery',
method: 'POST',
params: {
id
},
custom: {
isApiEncryption: false
}
})
}
export const getConAssayTaskWithReportTemplateContent = id => {
return request({
url: '/qms/config/assay-task/getConTaskWithReportTemplateDataContent',
method: 'get',
params: {
id
},
custom: {
isApiEncryption: false
}
})
}
export const queryTaskDetailListByAssayTaskId = params => {
return request({
url: taskPrefix + '/getAssayTaskDataWithDetailData',
method: 'get',
params: params,
custom: {
isApiEncryption: false
}
})
}
export default {
auncelWeigh,
auncelWeighRevoke,
getAssayTaskList,
weighBatchSubmitByTaskNo,
weighBatchSubmitByIds,
assayTaskReview,
reviewWeightTaskByTaskIdAndSampleIds,
assayTaskDetailReview,
assayTaskDetailRecovery,
getConAssayTaskWithReportTemplateContent,
queryTaskDetailListByAssayTaskId
}

43
nx/api/dailyCheck.js Normal file
View File

@@ -0,0 +1,43 @@
import request from '@/nx/request'
export default {
queryById: id =>
request({
url: '/lims/bus/deviceBusMaintain/getMaintainDetail',
method: 'GET',
params: { id }
}),
list: params =>
request({
url: '/lims/bus/deviceBusMaintain/list',
method: 'GET',
params
}),
// 根据设备id或者维护和点检记录
getCheckRecord: data =>
request({
url: '/lims/bus/deviceBusMaintain/createOrGet',
method: 'POST',
data
}),
submit: data =>
request({
url: '/lims/bus/deviceBusMaintain/saveMaintainVo',
method: 'POST',
data,
custom: {
showSuccess: true
}
}),
getLastDailyCheckOfToday: params =>
request({
url: '/lims/bus/deviceBusMaintain/getLastDailyCheckOfToday',
method: 'GET',
params,
}),
createDailyCheck: data =>
request({
url: '/lims/bus/deviceBusMaintain/create',
method: 'POST',
data
})
}

79
nx/api/deviceInfo.js Normal file
View File

@@ -0,0 +1,79 @@
import request from '@/nx/request'
export function getDeviceBusInfoById(id) {
return request({
url: '/lims/bus/deviceBusInfo/queryById',
method: 'GET',
params: { id }
})
}
export function deviceList(params) {
return request({
url: '/lims/bus/deviceBusInfo/list',
method: 'GET',
params
})
}
export function treeData(params) {
return request({
url: '/lims/bus/deviceBusProduct/listTree',
method: 'GET',
params
})
}
// 验收列表
export function acceptDetailList(params) {
return request({
url: '/lims/bus/device/accept-detail/queryBy',
method: 'GET',
params
})
}
export function scrapDetailList(params) {
return request({
url: '/lims/bus/device/scrap-detail/queryBy',
method: 'GET',
params
})
}
// 维修列表
export function repairList(params) {
return request({
url: '/lims/bus/repairResult/list',
method: 'GET',
params
})
}
// 借用列表
export function borrowList(params) {
return request({
url: '/lims/bus/device/borrow-detail/queryPageBy',
method: 'GET',
params
})
}
// 归还列表
export function givebackList(params) {
return request({
url: '/lims/bus/device/giveback-detail/queryPageBy',
method: 'GET',
params
})
}
export function scrapList(params) {
return request({
url: '/lims/bus/device/scrap-detail/queryPageBy',
method: 'GET',
params
})
}
export function stopList(params) {
return request({
url: '/lims/bus/device/stop-detail/queryPageBy',
method: 'GET',
params
})
}
export default{
getDeviceBusInfoById
}

10
nx/api/index.js Normal file
View File

@@ -0,0 +1,10 @@
const files = import.meta.glob('./*.js', { eager: true });
let api = {};
Object.keys(files).forEach((key) => {
api = {
...api,
[key.replace(/(.*\/)*([^.]+).*/gi, '$2')]: files[key].default,
};
});
export default api;

24
nx/api/laboratory.js Normal file
View File

@@ -0,0 +1,24 @@
import request from '@/nx/request'
//获取实验室设备
const getDeviceLaboratoryListBy = params => {
return request({
url: '/qms/lims/deviceLaboratory/list',
method: 'GET',
params: {
...params
}
})
}
// 获取平板端菜单
const getMenuForPAD = () => {
return request({
url: '/sys/permission/getMenuForPAD',
method: 'GET'
})
}
export default {
getDeviceLaboratoryListBy,
getMenuForPAD
}

77
nx/api/measure.js Normal file
View File

@@ -0,0 +1,77 @@
import request from '@/nx/request'
// 根据用户id获取计量点
const getMeasurePointByUserId = params => {
return request({
url: '/mas-iot/user-measure-point/listByUserId',
method: 'GET',
params: {
...params
},
custom: {
isApiEncryption: false
}
})
}
// 根据用户id及计量点id获取计量点
const getMeasurePointByUserIdAndMeasurePointId = params => {
return request({
url: '/mas-iot/user-measure-point/findByUserIdAndMeasurePointId',
method: 'GET',
params: {
...params
},
custom: {
isApiEncryption: false
}
})
}
//获取物料信息
const getGoodsListBy = params => {
return request({
url: '/mas-lims/bas-goods/oldGoodsListBy',
method: 'GET',
params: {
...params
},
custom: {
isApiEncryption: false
}
})
}
//获取发货方
const getSellerListBy = params => {
return request({
url: '/mas-lims/bas-businesses/oldSellerListBy',
method: 'GET',
params: {
...params
},
custom: {
isApiEncryption: false
}
})
}
//获取收货方
const getBuyerListBy = params => {
return request({
url: '/mas-lims/bas-businesses/oldBuyerListBy',
method: 'GET',
params: {
...params
},
custom: {
isApiEncryption: false
}
})
}
export default {
getGoodsListBy,
getSellerListBy,
getBuyerListBy,
getMeasurePointByUserId,
getMeasurePointByUserIdAndMeasurePointId
}

39
nx/api/sys.js Normal file
View File

@@ -0,0 +1,39 @@
import request from '@/nx/request'
export function getSysParameterBizByName(name) {
return request({
url: '/sys/sysParameterBiz/getSysParameterBizByName',
method: 'GET',
params: { name }
})
}
export default {
getSysParameterBizByName,
// 获取验证图片以及 token
getCaptchaCode: data => {
return request({
url: '/system/captcha/get',
method: 'POST',
data,
custom: {
showError: false,
showLoading: false,
isTransformResponse: false
}
})
},
// 滑动或者点选验证
verifyCaptcha: data => {
return request({
url: '/system/captcha/check',
method: 'POST',
data,
custom: {
showError: false,
showLoading: false,
isTransformResponse: false
}
})
}
}

38
nx/api/user.js Normal file
View File

@@ -0,0 +1,38 @@
import request from '@/nx/request'
export default {
// 账号登录
accountLogin: data =>
request({
url: '/system/auth/login',
method: 'POST',
data,
custom: {
loadingMsg: '登录中'
}
}),
// 获取用户权限信息
getInfo: () => {
return request({
url: '/system/auth/get-permission-info',
method: 'GET',
custom: {
showError: false,
showLoading: false
}
})
},
getRoleMenusByParentMenuKey: params =>
request({
url: '/sys/permission/getMenuByParentNodeUrl',
method: 'GET',
params
}),
getAppPermission: param => {
request({
params: param,
url: '/sys/app-client-role/getListByUserIdAndClientId',
method: 'GET'
})
}
}

33
nx/config/index.js Normal file
View File

@@ -0,0 +1,33 @@
import { get } from 'lodash'
// 开发环境配置
export let version
// 接口前缀
export const apiPath = import.meta.env.NX_API_PATH
// if (process.env.NODE_ENV === 'development') {
// console.log(import.meta.env)
// baseUrl = import.meta.env.NX_DEV_BASE_URL
// } else {
// }
version = import.meta.env.NX_VERSION
// if (typeof baseUrl === 'undefined') {
// console.error('请检查.env配置文件是否存在')
// } else {
// }
export const apiCrypto = {
type: 'sm4', //aes,des,sm4
aesKey: 'okK2ScfBoB0PzjTLVIlzp9z0R0CuPndE',
desKey: 'wMpDsJjgCL4sXMbY',
sm4Key: 'pMjhravzPN0TKm0j'
}
// 客户端密钥
export const clientSecret = ' 2E1TFEkR8YaOcLhp'
// 附件前缀
export const attachmentKey = 'lims_attachment'
export default {
apiPath,
apiCrypto,
clientSecret,
attachmentKey
}

6
nx/config/zbTable.js Normal file
View File

@@ -0,0 +1,6 @@
export function setCellHeaderStyle() {
return { background: '#f5f5f5', fontSize: '14px' }
}
export function setCellStyle(e) {
return { fontSize: '15px' }
}

View File

@@ -0,0 +1,290 @@
import { create, all, number, pow } from 'mathjs'
const math = create(all)
math.config({
number: 'BigNumber',
precision: 64
})
/*
* 计算分析值*/
export function calcAnalysisValue(group) {
try {
for (const g of group) {
for (const ele of g.fields) {
if (!ele.formula || ele.formula == '') continue
if (ele.valueTypeManual && ele.valueTypeManual == '1') continue
let formula = ele.formula
let formulas = formula.split('|')
let formulaVal = ''
let hasNullVal = false
formulas.forEach(f => {
let value = ''
if (f.charAt(0) === 'p') {
// let o = elementParamValueData.find((i) => 'p' + i.paramNo === f);
let o = findFieldInGroup(f, group, 'p')
value = o.value
} else if (f.charAt(0) === 'e') {
// let o = elementParamValueData.find((i) => 'e' + i.paramNo === f);
let o = findFieldInGroup(f, group, 'e')
value = o.value
} else if (f.charAt(0) === '<' || f.charAt(0) === '>') {
value = "'" + f + "'"
} else {
value = f
}
if (typeof value == 'undefined' || value == null) {
hasNullVal = true
return true
}
formulaVal += value
})
if (hasNullVal) {
ele.value = null
continue
}
let v
if (formulaVal.startsWith('Get')) {
//计算公式为Get开头的都是执行方法
v = eval(formulaVal)
} else {
v = math.evaluate(formulaVal).toString()
v = isFinite(v) ? v.toString() : ''
}
ele.value = handleRoundFiveNumber(v, ele.dataType)
}
}
} catch (error) {
console.log(error)
}
}
const findFieldInGroup = function (paramNo, group, p) {
for (const g of group) {
for (const f of g.fields) {
if (p + f.paramNo === paramNo) {
return f
}
}
}
return { value: null }
}
const GetRecoveryRate = function (elementFormulaCode, value) {
// //读取conRecoveryRateList
const conRecoveryRateList = uni.getStorageSync('ConRecoveryRateList')
if (!conRecoveryRateList) return
let o = conRecoveryRateList.find(i => {
//console.log("取得的" + i + "回收率:" + i);
if (value === 0) {
return i.elementFormulaCode === elementFormulaCode && i.minValue === value
}
return i.elementFormulaCode === elementFormulaCode && i.minValue < value && value <= i.maxValue
})
// console.log(o);
const rate = o ? o.rate : 100
// console.log("取得的" + elementFormulaCode + "回收率:" + rate);
return rate
// console.log("执行方法GetRecoveryRate");
// return 100;
}
/*
* 根据硫值计算:支持碳、硝酸钾(滇中)
* 当S%<22%时,需加入淀粉的量=(75-S%*22*M)/12
* 当 S%>22%时,需加入硝酸钾的量=(S%*22*M-75)/4
* 当 S%==22%时硝酸钾为0淀粉为空
* sValueKey硫值对应的dicKey
* weightKey重量对应的dicKey
* percent计算参数
*
* 举例Get_C_KNO3_bySValue|(|p14|, |p2|, |>|)
* */
const Get_C_KNO3_bySValue = function (sValue, weight, operator) {
//判断sValue是数字
if (isNaN(sValue) || isNaN(weight)) {
return ''
}
let v = number(sValue)
const w = number(weight)
if (w === 0) return ''
v = v * 0.01
//当S%<22%时,需加入淀粉的量=(75-S%*22*M)/12
if (operator === '<' && v < 0.22) {
// return ( 75 - v * 22 * w )/12;
return accDiv(accSub(75, accMul(accMul(v, 22), w)), 12)
}
//S%>22%时,需加入硝酸钾的量=(S%*22*M-75)/4
if (operator === '>=' && v >= 0.22) {
//S%==22%时硝酸钾为0淀粉为空
if (v === 22) return 0
// return ( v * 22 * w - 75 ) + 44;
return accDiv(accSub(accMul(v, accMul(22, w)), 75), 4)
}
return ''
}
/** 处理数值数据:四舍六入奇进偶不进
* 1如果取小数的最后一位为55前为奇数进位为偶不进,五后非零就进一,五后皆零看奇偶,五前为偶应舍去,五前为奇要进一
* 2.5后不为0时就入为0时看5前奇进偶不进
* 3.四舍,六入
* 传入数值和保留位数
*/
export function handleRoundFiveNumber(number, fixed = 0) {
if (number == null || number === '' || isNaN(number)) return number
if (fixed === -1) return number
number = String(number)
//可以考虑清掉末尾的0暂时限制了不会有,因为传入数值末尾0是去掉的
const index = number.indexOf('.')
if (index == -1) {
if (fixed > 0) {
number += '.'
}
for (let i = 0; i < fixed; i++) {
number += '0'
}
//补0返回
return number
}
//取到保留小数位的下一位5.5555取保留俩位,那就是小数点后第三位
const indexFixed = index + fixed + 1
if (indexFixed >= number.length) {
//如果小数位数不够, 补0直接返回
const zerolen = indexFixed - number.length
for (let i = 0; i < zerolen; i++) {
number += '0'
}
return number
}
//取保留位数的后一位做判断以下是有5的判断
const endNumber = number.substr(indexFixed, 1)
if (endNumber != '5') {
//如果做判断的数不是五就按正常的四舍五入即忽略了5后面补0的那些由于是数字传进来0已经去掉此处不做处理
return Number(number).toFixed(fixed)
}
if (indexFixed != number.length - 1) {
//由于当前判断位不是最后一位而又去除了0那么后面后的位数应该直接入位五后不为0时入,由于会有小于五的四舍五入肯定不行那么只能截取到当前保留位数然后转成数字加上10的负fixed的次方即可
number = number.substring(0, indexFixed)
if (number.indexOf('-') != -1) {
//需要考虑到负数的情况
return (Number(number) - Number(Math.pow(10, -fixed))).toFixed(fixed)
}
return (Number(number) + Number(Math.pow(10, -fixed))).toFixed(fixed)
//return this.accAdd(number,Math.pow(10,-fixed))
}
//接下来就时五后没有值也就是0的需要看前面的奇入偶不入了取当前位的上一位
let twoNumber = number.substr(indexFixed - 1, 1)
if (twoNumber == '.') {
//取到小数点,再取一次,要取到小数点左边第一位
twoNumber = number.substr(indexFixed - 2, 1)
}
if ('13579'.indexOf(twoNumber) != -1) {
//奇进
number = number.substring(0, indexFixed)
if (number.indexOf('-') != -1) {
//需要考虑到负数的情况
return (Number(number) - Math.pow(10, -fixed)).toFixed(fixed)
}
return (Number(number) + Math.pow(10, -fixed)).toFixed(fixed)
}
//偶不进,将取值的当前位数,直接截取字符即可
return number.substr(0, indexFixed)
}
/**
** 除法函数,用来得到精确的除法结果
** 说明javascript的除法结果会有误差在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
** 调用accDiv(arg1,arg2)
** 返回值arg1除以arg2的精确结果
**/
function accDiv(arg1, arg2) {
var t1 = 0,
t2 = 0,
r1,
r2
try {
t1 = arg1.toString().split('.')[1].length
} catch (e) {}
try {
t2 = arg2.toString().split('.')[1].length
} catch (e) {}
r1 = Number(arg1.toString().replace('.', ''))
r2 = Number(arg2.toString().replace('.', ''))
return (r1 / r2) * pow(10, t2 - t1)
}
/**
** 乘法函数,用来得到精确的乘法结果
** 说明javascript的乘法结果会有误差在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
** 调用accMul(arg1,arg2)
** 返回值arg1乘以 arg2的精确结果
**/
function accMul(arg1, arg2) {
var m = 0,
s1 = arg1.toString(),
s2 = arg2.toString()
try {
m += s1.split('.')[1].length
} catch (e) {}
try {
m += s2.split('.')[1].length
} catch (e) {}
return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / Math.pow(10, m)
}
/**
** 减法函数,用来得到精确的减法结果
** 说明javascript的减法结果会有误差在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
** 调用accSub(arg1,arg2)
** 返回值arg1加上arg2的精确结果
**/
function accSub(arg1, arg2) {
var r1, r2, m, n
try {
r1 = arg1.toString().split('.')[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split('.')[1].length
} catch (e) {
r2 = 0
}
m = Math.pow(10, Math.max(r1, r2)) //last modify by deeka //动态控制精度长度
n = r1 >= r2 ? r1 : r2
return ((arg1 * m - arg2 * m) / m).toFixed(n)
}
/**
** 加法函数,用来得到精确的加法结果
** 说明javascript的加法结果会有误差在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
** 调用accAdd(arg1,arg2)
** 返回值arg1加上arg2的精确结果
**/
function accAdd(arg1, arg2) {
var r1, r2, m, c
try {
r1 = arg1.toString().split('.')[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split('.')[1].length
} catch (e) {
r2 = 0
}
c = Math.abs(r1 - r2)
m = Math.pow(10, Math.max(r1, r2))
if (c > 0) {
var cm = Math.pow(10, c)
if (r1 > r2) {
arg1 = Number(arg1.toString().replace('.', ''))
arg2 = Number(arg2.toString().replace('.', '')) * cm
} else {
arg1 = Number(arg1.toString().replace('.', '')) * cm
arg2 = Number(arg2.toString().replace('.', ''))
}
} else {
arg1 = Number(arg1.toString().replace('.', ''))
arg2 = Number(arg2.toString().replace('.', ''))
}
return (arg1 + arg2) / m
}

168
nx/helper/digit.js Normal file
View File

@@ -0,0 +1,168 @@
let _boundaryCheckingState = true; // 是否进行越界检查的全局开关
/**
* 把错误的数据转正
* @private
* @example strip(0.09999999999999998)=0.1
*/
function strip(num, precision = 15) {
return +parseFloat(Number(num).toPrecision(precision));
}
/**
* Return digits length of a number
* @private
* @param {*number} num Input number
*/
function digitLength(num) {
// Get digit length of e
const eSplit = num.toString().split(/[eE]/);
const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
return len > 0 ? len : 0;
}
/**
* 把小数转成整数,如果是小数则放大成整数
* @private
* @param {*number} num 输入数
*/
function float2Fixed(num) {
if (num.toString().indexOf('e') === -1) {
return Number(num.toString().replace('.', ''));
}
const dLen = digitLength(num);
return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);
}
/**
* 检测数字是否越界,如果越界给出提示
* @private
* @param {*number} num 输入数
*/
function checkBoundary(num) {
if (_boundaryCheckingState) {
if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
console.warn(`${num} 超出了精度限制,结果可能不正确`);
}
}
}
/**
* 把递归操作扁平迭代化
* @param {number[]} arr 要操作的数字数组
* @param {function} operation 迭代操作
* @private
*/
function iteratorOperation(arr, operation) {
const [num1, num2, ...others] = arr;
let res = operation(num1, num2);
others.forEach((num) => {
res = operation(res, num);
});
return res;
}
/**
* 高精度乘法
* @export
*/
export function times(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, times);
}
const [num1, num2] = nums;
const num1Changed = float2Fixed(num1);
const num2Changed = float2Fixed(num2);
const baseNum = digitLength(num1) + digitLength(num2);
const leftValue = num1Changed * num2Changed;
checkBoundary(leftValue);
return leftValue / Math.pow(10, baseNum);
}
/**
* 高精度加法
* @export
*/
export function plus(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, plus);
}
const [num1, num2] = nums;
// 取最大的小数位
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
// 把小数都转为整数然后再计算
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
}
/**
* 高精度减法
* @export
*/
export function minus(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, minus);
}
const [num1, num2] = nums;
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
}
/**
* 高精度除法
* @export
*/
export function divide(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, divide);
}
const [num1, num2] = nums;
const num1Changed = float2Fixed(num1);
const num2Changed = float2Fixed(num2);
checkBoundary(num1Changed);
checkBoundary(num2Changed);
// 重要这里必须用strip进行修正
return times(
num1Changed / num2Changed,
strip(Math.pow(10, digitLength(num2) - digitLength(num1))),
);
}
/**
* 四舍五入
* @export
*/
export function round(num, ratio) {
const base = Math.pow(10, ratio);
let result = divide(Math.round(Math.abs(times(num, base))), base);
if (num < 0 && result !== 0) {
result = times(result, -1);
}
// 位数不足则补0
return result;
}
/**
* 是否进行边界检查,默认开启
* @param flag 标记开关true 为开启false 为关闭,默认为 true
* @export
*/
export function enableBoundaryChecking(flag = true) {
_boundaryCheckingState = flag;
}
export default {
times,
plus,
minus,
divide,
round,
enableBoundaryChecking,
};

749
nx/helper/index.js Normal file
View File

@@ -0,0 +1,749 @@
import test from './test.js'
import { round } from './digit.js'
/**
* @description 如果value小于min取min如果value大于max取max
* @param {number} min
* @param {number} max
* @param {number} value
*/
function range(min = 0, max = 0, value = 0) {
return Math.max(min, Math.min(max, Number(value)))
}
/**
* @description 用于获取用户传递值的px值 如果用户传递了"xxpx"或者"xxrpx",取出其数值部分,如果是"xxxrpx"还需要用过uni.upx2px进行转换
* @param {number|string} value 用户传递值的px值
* @param {boolean} unit
* @returns {number|string}
*/
export function getPx(value, unit = false) {
if (test.number(value)) {
return unit ? `${value}px` : Number(value)
}
// 如果带有rpx先取出其数值部分再转为px值
if (/(rpx|upx)$/.test(value)) {
return unit ? `${uni.upx2px(parseInt(value))}px` : Number(uni.upx2px(parseInt(value)))
}
return unit ? `${parseInt(value)}px` : parseInt(value)
}
/**
* @description 进行延时,以达到可以简写代码的目的
* @param {number} value 堵塞时间 单位ms 毫秒
* @returns {Promise} 返回promise
*/
export function sleep(value = 30) {
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, value)
})
}
/**
* @description 运行期判断平台
* @returns {string} 返回所在平台(小写)
* @link 运行期判断平台 https://uniapp.dcloud.io/frame?id=判断平台
*/
export function os() {
return uni.getSystemInfoSync().platform.toLowerCase()
}
/**
* @description 获取系统信息同步接口
* @link 获取系统信息同步接口 https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync
*/
export function sys() {
return uni.getSystemInfoSync()
}
/**
* @description 取一个区间数
* @param {Number} min 最小值
* @param {Number} max 最大值
*/
function random(min, max) {
if (min >= 0 && max > 0 && max >= min) {
const gab = max - min + 1
return Math.floor(Math.random() * gab + min)
}
return 0
}
/**
* @param {Number} len uuid的长度
* @param {Boolean} firstU 将返回的首字母置为"u"
* @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制
*/
export function guid(len = 32, firstU = true, radix = null) {
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
const uuid = []
radix = radix || chars.length
if (len) {
// 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
} else {
let r
// rfc4122标准要求返回的uuid中,某些位为固定的字符
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
uuid[14] = '4'
for (let i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | (Math.random() * 16)
uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]
}
}
}
// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
if (firstU) {
uuid.shift()
return `u${uuid.join('')}`
}
return uuid.join('')
}
/**
* @description 获取父组件的参数因为支付宝小程序不支持provide/inject的写法
this.$parent在非H5中可以准确获取到父组件但是在H5中需要多次this.$parent.$parent.xxx
这里默认值等于undefined有它的含义因为最顶层元素(组件)的$parent就是undefined意味着不传name
值(默认为undefined),就是查找最顶层的$parent
* @param {string|undefined} name 父组件的参数名
*/
export function $parent(name = undefined) {
let parent = this.$parent
// 通过while历遍这里主要是为了H5需要多层解析的问题
while (parent) {
// 父组件
if (parent.$options && parent.$options.name !== name) {
// 如果组件的name不相等继续上一级寻找
parent = parent.$parent
} else {
return parent
}
}
return false
}
/**
* @description 样式转换
* 对象转字符串,或者字符串转对象
* @param {object | string} customStyle 需要转换的目标
* @param {String} target 转换的目的object-转为对象string-转为字符串
* @returns {object|string}
*/
export function addStyle(customStyle, target = 'object') {
// 字符串转字符串,对象转对象情形,直接返回
if (
test.empty(customStyle) ||
(typeof customStyle === 'object' && target === 'object') ||
(target === 'string' && typeof customStyle === 'string')
) {
return customStyle
}
// 字符串转对象
if (target === 'object') {
// 去除字符串样式中的两端空格(中间的空格不能去掉比如padding: 20px 0如果去掉了就错了),空格是无用的
customStyle = trim(customStyle)
// 根据";"将字符串转为数组形式
const styleArray = customStyle.split(';')
const style = {}
// 历遍数组,拼接成对象
for (let i = 0; i < styleArray.length; i++) {
// 'font-size:20px;color:red;',如此最后字符串有";"的话会导致styleArray最后一个元素为空字符串这里需要过滤
if (styleArray[i]) {
const item = styleArray[i].split(':')
style[trim(item[0])] = trim(item[1])
}
}
return style
}
// 这里为对象转字符串形式
let string = ''
for (const i in customStyle) {
// 驼峰转为中划线的形式否则css内联样式无法识别驼峰样式属性名
const key = i.replace(/([A-Z])/g, '-$1').toLowerCase()
string += `${key}:${customStyle[i]};`
}
// 去除两端空格
return trim(string)
}
/**
* @description 添加单位如果有rpxupx%px等单位结尾或者值为auto直接返回否则加上px单位结尾
* @param {string|number} value 需要添加单位的值
* @param {string} unit 添加的单位名 比如px
*/
export function addUnit(value = 'auto', unit = 'px') {
value = String(value)
return test.number(value) ? `${value}${unit}` : value
}
/**
* @description 深度克隆
* @param {object} obj 需要深度克隆的对象
* @returns {*} 克隆后的对象或者原值(不是对象)
*/
function deepClone(obj) {
// 对常见的“非”值,直接返回原来值
if ([null, undefined, NaN, false].includes(obj)) return obj
if (typeof obj !== 'object' && typeof obj !== 'function') {
// 原始类型直接返回
return obj
}
const o = test.array(obj) ? [] : {}
for (const i in obj) {
if (obj.hasOwnProperty(i)) {
o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
}
}
return o
}
/**
* @description JS对象深度合并
* @param {object} target 需要拷贝的对象
* @param {object} source 拷贝的来源对象
* @returns {object|boolean} 深度合并后的对象或者false入参有不是对象
*/
export function deepMerge(target = {}, source = {}) {
target = deepClone(target)
if (typeof target !== 'object' || typeof source !== 'object') return false
for (const prop in source) {
if (!source.hasOwnProperty(prop)) continue
if (prop in target) {
if (typeof target[prop] !== 'object') {
target[prop] = source[prop]
} else if (typeof source[prop] !== 'object') {
target[prop] = source[prop]
} else if (target[prop].concat && source[prop].concat) {
target[prop] = target[prop].concat(source[prop])
} else {
target[prop] = deepMerge(target[prop], source[prop])
}
} else {
target[prop] = source[prop]
}
}
return target
}
/**
* @description error提示
* @param {*} err 错误内容
*/
function error(err) {
// 开发环境才提示,生产环境不会提示
if (process.env.NODE_ENV === 'development') {
console.error(`SheepJS:${err}`)
}
}
/**
* @description 打乱数组
* @param {array} array 需要打乱的数组
* @returns {array} 打乱后的数组
*/
function randomArray(array = []) {
// 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0
return array.sort(() => Math.random() - 0.5)
}
// padStart 的 polyfill因为某些机型或情况还无法支持es7的padStart比如电脑版的微信小程序
// 所以这里做一个兼容polyfill的兼容处理
if (!String.prototype.padStart) {
// 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解
String.prototype.padStart = function (maxLength, fillString = ' ') {
if (Object.prototype.toString.call(fillString) !== '[object String]') {
throw new TypeError('fillString must be String')
}
const str = this
// 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉
if (str.length >= maxLength) return String(str)
const fillLength = maxLength - str.length
let times = Math.ceil(fillLength / fillString.length)
while ((times >>= 1)) {
fillString += fillString
if (times === 1) {
fillString += fillString
}
}
return fillString.slice(0, fillLength) + str
}
}
/**
* @description 格式化时间
* @param {String|Number} dateTime 需要格式化的时间戳
* @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd
* @returns {string} 返回格式化后的字符串
*/
function timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') {
let date
// 若传入时间为假值,则取当前时间
if (!dateTime) {
date = new Date()
}
// 若为unix秒时间戳则转为毫秒时间戳逻辑有点奇怪但不敢改以保证历史兼容
else if (/^\d{10}$/.test(dateTime?.toString().trim())) {
date = new Date(dateTime * 1000)
}
// 若用户传入字符串格式时间戳new Date无法解析需做兼容
else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) {
date = new Date(Number(dateTime))
}
// 其他都认为符合 RFC 2822 规范
else {
// 处理平台性差异在Safari/Webkit中new Date仅支持/作为分割符的字符串时间
date = new Date(typeof dateTime === 'string' ? dateTime.replace(/-/g, '/') : dateTime)
}
const timeSource = {
y: date.getFullYear().toString(), // 年
m: (date.getMonth() + 1).toString().padStart(2, '0'), // 月
d: date.getDate().toString().padStart(2, '0'), // 日
h: date.getHours().toString().padStart(2, '0'), // 时
M: date.getMinutes().toString().padStart(2, '0'), // 分
s: date.getSeconds().toString().padStart(2, '0') // 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
}
for (const key in timeSource) {
const [ret] = new RegExp(`${key}+`).exec(formatStr) || []
if (ret) {
// 年可能只需展示两位
const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0
formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex))
}
}
return formatStr
}
/**
* @description 时间戳转为多久之前
* @param {String|Number} timestamp 时间戳
* @param {String|Boolean} format
* 格式化规则如果为时间格式字符串,超出一定时间范围,返回固定的时间格式;
* 如果为布尔值false无论什么时间都返回多久以前的格式
* @returns {string} 转化后的内容
*/
function timeFrom(timestamp = null, format = 'yyyy-mm-dd') {
if (timestamp == null) timestamp = Number(new Date())
timestamp = parseInt(timestamp)
// 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
if (timestamp.toString().length == 10) timestamp *= 1000
let timer = new Date().getTime() - timestamp
timer = parseInt(timer / 1000)
// 如果小于5分钟,则返回"刚刚",其他以此类推
let tips = ''
switch (true) {
case timer < 300:
tips = '刚刚'
break
case timer >= 300 && timer < 3600:
tips = `${parseInt(timer / 60)}分钟前`
break
case timer >= 3600 && timer < 86400:
tips = `${parseInt(timer / 3600)}小时前`
break
case timer >= 86400 && timer < 2592000:
tips = `${parseInt(timer / 86400)}天前`
break
default:
// 如果format为false则无论什么时间戳都显示xx之前
if (format === false) {
if (timer >= 2592000 && timer < 365 * 86400) {
tips = `${parseInt(timer / (86400 * 30))}个月前`
} else {
tips = `${parseInt(timer / (86400 * 365))}年前`
}
} else {
tips = timeFormat(timestamp, format)
}
}
return tips
}
/**
* @description 去除空格
* @param String str 需要去除空格的字符串
* @param String pos both(左右)|left|right|all 默认both
*/
function trim(str, pos = 'both') {
str = String(str)
if (pos == 'both') {
return str.replace(/^\s+|\s+$/g, '')
}
if (pos == 'left') {
return str.replace(/^\s*/, '')
}
if (pos == 'right') {
return str.replace(/(\s*$)/g, '')
}
if (pos == 'all') {
return str.replace(/\s+/g, '')
}
return str
}
/**
* @description 对象转url参数
* @param {object} data,对象
* @param {Boolean} isPrefix,是否自动加上"?"
* @param {string} arrayFormat 规则 indices|brackets|repeat|comma
*/
function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') {
const prefix = isPrefix ? '?' : ''
const _result = []
if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets'
for (const key in data) {
const value = data[key]
// 去掉为空的参数
if (['', undefined, null].indexOf(value) >= 0) {
continue
}
// 如果值为数组,另行处理
if (value.constructor === Array) {
// e.g. {ids: [1, 2, 3]}
switch (arrayFormat) {
case 'indices':
// 结果: ids[0]=1&ids[1]=2&ids[2]=3
for (let i = 0; i < value.length; i++) {
_result.push(`${key}[${i}]=${value[i]}`)
}
break
case 'brackets':
// 结果: ids[]=1&ids[]=2&ids[]=3
value.forEach(_value => {
_result.push(`${key}[]=${_value}`)
})
break
case 'repeat':
// 结果: ids=1&ids=2&ids=3
value.forEach(_value => {
_result.push(`${key}=${_value}`)
})
break
case 'comma':
// 结果: ids=1,2,3
let commaStr = ''
value.forEach(_value => {
commaStr += (commaStr ? ',' : '') + _value
})
_result.push(`${key}=${commaStr}`)
break
default:
value.forEach(_value => {
_result.push(`${key}[]=${_value}`)
})
}
} else {
_result.push(`${key}=${value}`)
}
}
return _result.length ? prefix + _result.join('&') : ''
}
/**
* 显示消息提示框
* @param {String} title 提示的内容,长度与 icon 取值有关。
* @param {Number} duration 提示的延迟时间单位毫秒默认2000
*/
function toast(title, duration = 2000) {
uni.showToast({
title: String(title),
icon: 'none',
duration
})
}
/**
* @description 根据主题type值,获取对应的图标
* @param {String} type 主题名称,primary|info|error|warning|success
* @param {boolean} fill 是否使用fill填充实体的图标
*/
function type2icon(type = 'success', fill = false) {
// 如果非预置值,默认为success
if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success'
let iconName = ''
// 目前(2019-12-12),info和primary使用同一个图标
switch (type) {
case 'primary':
iconName = 'info-circle'
break
case 'info':
iconName = 'info-circle'
break
case 'error':
iconName = 'close-circle'
break
case 'warning':
iconName = 'error-circle'
break
case 'success':
iconName = 'checkmark-circle'
break
default:
iconName = 'checkmark-circle'
}
// 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的
if (fill) iconName += '-fill'
return iconName
}
/**
* @description 数字格式化
* @param {number|string} number 要格式化的数字
* @param {number} decimals 保留几位小数
* @param {string} decimalPoint 小数点符号
* @param {string} thousandsSeparator 千分位符号
* @returns {string} 格式化后的数字
*/
function priceFormat(number, decimals = 0, decimalPoint = '.', thousandsSeparator = ',') {
number = `${number}`.replace(/[^0-9+-Ee.]/g, '')
const n = !isFinite(+number) ? 0 : +number
const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
const sep = typeof thousandsSeparator === 'undefined' ? ',' : thousandsSeparator
const dec = typeof decimalPoint === 'undefined' ? '.' : decimalPoint
let s = ''
s = (prec ? round(n, prec) + '' : `${Math.round(n)}`).split('.')
const re = /(-?\d+)(\d{3})/
while (re.test(s[0])) {
s[0] = s[0].replace(re, `$1${sep}$2`)
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || ''
s[1] += new Array(prec - s[1].length + 1).join('0')
}
return s.join(dec)
}
/**
* @description 获取duration值
* 如果带有ms或者s直接返回如果大于一定值认为是ms单位小于一定值认为是s单位
* 比如以30位阈值那么300大于30可以理解为用户想要的是300ms而不是想花300s去执行一个动画
* @param {String|number} value 比如: "1s"|"100ms"|1|100
* @param {boolean} unit 提示: 如果是false 默认返回number
* @return {string|number}
*/
function getDuration(value, unit = true) {
const valueNum = parseInt(value)
if (unit) {
if (/s$/.test(value)) return value
return value > 30 ? `${value}ms` : `${value}s`
}
if (/ms$/.test(value)) return valueNum
if (/s$/.test(value)) return valueNum > 30 ? valueNum : valueNum * 1000
return valueNum
}
/**
* @description 日期的月或日补零操作
* @param {String} value 需要补零的值
*/
function padZero(value) {
return `00${value}`.slice(-2)
}
/**
* @description 获取某个对象下的属性,用于通过类似'a.b.c'的形式去获取一个对象的的属性的形式
* @param {object} obj 对象
* @param {string} key 需要获取的属性字段
* @returns {*}
*/
function getProperty(obj, key) {
if (!obj) {
return
}
if (typeof key !== 'string' || key === '') {
return ''
}
if (key.indexOf('.') !== -1) {
const keys = key.split('.')
let firstObj = obj[keys[0]] || {}
for (let i = 1; i < keys.length; i++) {
if (firstObj) {
firstObj = firstObj[keys[i]]
}
}
return firstObj
}
return obj[key]
}
/**
* @description 设置对象的属性值,如果'a.b.c'的形式进行设置
* @param {object} obj 对象
* @param {string} key 需要设置的属性
* @param {string} value 设置的值
*/
function setProperty(obj, key, value) {
if (!obj) {
return
}
// 递归赋值
const inFn = function (_obj, keys, v) {
// 最后一个属性key
if (keys.length === 1) {
_obj[keys[0]] = v
return
}
// 0~length-1个key
while (keys.length > 1) {
const k = keys[0]
if (!_obj[k] || typeof _obj[k] !== 'object') {
_obj[k] = {}
}
const key = keys.shift()
// 自调用判断是否存在属性,不存在则自动创建对象
inFn(_obj[k], keys, v)
}
}
if (typeof key !== 'string' || key === '') {
} else if (key.indexOf('.') !== -1) {
// 支持多层级赋值操作
const keys = key.split('.')
inFn(obj, keys, value)
} else {
obj[key] = value
}
}
/**
* @description 获取当前页面路径
*/
function page() {
const pages = getCurrentPages()
// 某些特殊情况下(比如页面进行redirectTo时的一些时机)pages可能为空数组
return `/${pages[pages.length - 1]?.route ?? ''}`
}
/**
* @description 获取当前路由栈实例数组
*/
function pages() {
const pages = getCurrentPages()
return pages
}
/**
* 获取H5-真实根地址 兼容hash+history模式
*/
export function getRootUrl() {
let url = ''
// #ifdef H5
url = location.origin + location.pathname
if (location.hash !== '') {
url += '#/'
}
// #endif
return url
}
/**
* copyText 多端复制文本
*/
export function copyText(text) {
// #ifndef H5
uni.setClipboardData({
data: text,
success: function () {
toast('复制成功!')
},
fail: function () {
toast('复制失败!')
}
})
// #endif
// #ifdef H5
var createInput = document.createElement('textarea')
createInput.value = text
document.body.appendChild(createInput)
createInput.select()
document.execCommand('Copy')
createInput.className = 'createInput'
createInput.style.display = 'none'
toast('复制成功')
// #endif
}
// 提示
const showToast = (data = {}) => {
if (typeof data == 'string') {
uni.showToast({
title: data,
icon: 'none'
})
} else {
uni.showToast({
title: data.title,
icon: data.icon || 'none',
image: data.image || '',
mask: data.mask || false,
position: data.position || 'center',
duration: data.duration || 1500,
success: () => {
setTimeout(() => {
if (data.back) return uni.navigateBack()
data.success && data.success()
}, data.duration || 1500)
}
})
}
}
//uuid生成
const uuid = () => {
var s = []
var hexDigits = '0123456789abcdef'
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
}
s[14] = '4' // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = '-'
var uuid = s.join('')
return uuid
}
export default {
range,
getPx,
sleep,
os,
sys,
random,
guid,
$parent,
addStyle,
addUnit,
deepClone,
deepMerge,
error,
randomArray,
timeFormat,
timeFrom,
trim,
queryParams,
toast,
type2icon,
priceFormat,
getDuration,
padZero,
getProperty,
setProperty,
page,
pages,
test,
getRootUrl,
copyText,
showToast,
uuid
}

179
nx/helper/measure.js Normal file
View File

@@ -0,0 +1,179 @@
import { getWebSocketUrl } from '@/defaultBaseUrl'
export default {
isOpen: false,
isOpening: false,
socketTask: false,
timeoutID: -1,
regData: '',
webSocketUrl: getWebSocketUrl(),
//开始心跳
heartbeatStart() {
if (this.timeoutID != -1) {
this.heartbeatClear()
}
this.timeoutID = setTimeout(() => {
this.socketTask.send({
data: 'ping'
})
}, 15000)
},
//清理心跳
heartbeatClear() {
clearTimeout(this.timeoutID)
},
//重置心跳
heartbeatReset() {
this.heartbeatClear()
this.heartbeatStart()
},
//注册用户
regUser() {
this.socketTask.send({
data: this.regData
})
},
//设置连接注册数据
setRegData(regData) {
this.regData = regData
},
//打开连接
open() {
if (this.regData === '') {
console.log('请先调用setRegData方法设置注册数据')
return
}
//防止重复连接
if (this.isOpening) {
console.log('WebSocket正在连接。。。')
return
}
if (this.isOpen && this.socketTask) {
console.log('WebSocket已连接。。。')
return
}
// console.log("WebSocket开始连接。。。");
this.isOpening = true
let socketTask = uni.connectSocket({
url: this.webSocketUrl,
header: {
'content-type': 'application/json'
},
success: e => {
// console.log(e);
},
complete: () => {}
})
if (!socketTask) return
// console.log(socketTask);
this.socketTask = socketTask
//监听开启
socketTask.onOpen(res => {
this.isOpen = true
this.isOpening = false
// console.log("WebSocket连接成功。。。");
this.regUser(this.regData)
})
//监听消息
socketTask.onMessage(res => {
if (res.data.replace(/^\s+|\s+$/g, '') === 'pong') {
this.heartbeatReset()
return
}
let data = JSON.parse(res.data)
this.message(data)
})
//监听关闭
socketTask.onClose(res => {
this.isOpen = false
this.isOpening = false
this.socketTask = false
// console.log("WebSocket连接关闭。。。");
uni.$emit('connClose', res)
this.heartbeatClear()
this.reOpen()
})
//监听错误
socketTask.onError(res => {
this.isOpen = false
this.isOpening = false
this.socketTask = false
console.log('WebSocket连接失败。。。')
this.heartbeatClear()
this.reOpen()
})
},
//消息处理
message(data) {
switch (data.cmd) {
case 'replyRegister':
if (data.data.success) {
console.log('注册成功!')
//注册成功开始心跳
this.heartbeatStart()
}
break
case 'replyControlMeasurePoint':
uni.$emit('controlMeasurePoint', data)
break
case 'replyControlDevice':
uni.$emit('controlDevice', data.data)
break
case 'deviceStatus':
uni.$emit('deviceStatus', data.data)
break
case 'deviceData':
uni.$emit('deviceData', data.data)
break
case 'sellerData':
uni.$emit('sellerData', data.data)
break
case 'buyerData':
uni.$emit('buyerData', data.data)
break
case 'goodsData':
uni.$emit('goodsData', data.data)
break
case 'logData':
uni.$emit('logData', data.data)
break
case 'measurePointStatus':
uni.$emit('measurePointStatus', data.data)
break
case 'replyMeasureData':
uni.$emit('replyMeasureData', data.data)
break
case 'replySaveMeasureData':
uni.$emit('replySaveMeasureData', data.data)
break
}
},
//重新打开
reOpen() {
this.timeoutID = setTimeout(() => {
this.open()
}, 5000)
},
//关闭连接
close() {
if (this.isOpen) {
this.socketTask.close()
}
},
//发送消息
send(data) {
console.log('发送消息。。。')
if (!this.isOpen) {
//关闭则打开
this.open()
}
if (this.socketTask) {
this.socketTask.send({
data: data
})
}
}
}

233
nx/helper/print.js Normal file
View File

@@ -0,0 +1,233 @@
import { getConAssayTaskWithReportTemplateContent, queryTaskDetailListByAssayTaskId } from '@/nx/api/auncel'
export default {
//打印机Map对象
printMap: new Map(),
//检测连接
checkConnect(printer) {
printer.intervalID = setInterval(() => {
let iv = new Date().getTime() - printer.lastReceiveMessageTime //多久没接收到消息
if (iv > 30000) {
//如果超过30秒未接收到服务器消息则关闭连接
console.log('已经' + iv + 'ms没接收到消息了服务器估计没在了')
clearInterval(printer.intervalID)
printer.socketTask.close()
}
}, 20000)
},
//开始心跳
heartbeatStart(printer) {
printer.timeoutID = setTimeout(() => {
let heartbeatData = {
cmd: 'heartbeat',
data: 'ping'
}
console.log(printer.printServerIp + ': 发送心跳。。。')
printer.socketTask.send({
data: JSON.stringify(heartbeatData)
})
}, 10000)
},
//清理心跳
heartbeatClear(printer) {
clearTimeout(printer.timeoutID)
},
//重置心跳
heartbeatReset(printer) {
this.heartbeatClear(printer)
this.heartbeatStart(printer)
},
//打开连接
open(printServerIp, printServerPort = 22333) {
//判断是否存在
let printer = this.printMap.get(printServerIp)
if (!printer) {
printer = {
isOpen: false,
isOpening: false, //打开中
socketTask: false,
timeoutID: -1,
intervalID: -1,
reConnectCount: 0, //重新连接次数
printServerIp: printServerIp,
printServerPort: printServerPort,
lastReceiveMessageTime: new Date().getTime()
}
}
//如果为正在打开,则返回
if (printer.isOpening) {
// console.log("已经正在打开中。。。");
return
}
//防止重复连接
if (printer.isOpen && printer.socketTask) {
console.log('websocket连接已打开。。。')
return
}
// console.log(printServerIp + ": WebSocket开始连接。。。");
printer.isOpening = true
let socketTask = uni.connectSocket({
url: 'ws://' + printServerIp + ':' + printServerPort + '/',
header: {
'content-type': 'application/json'
},
success: e => {
//连接成功是需要监听onOpen。这里的成功只是创建接口调用成功
//console.log(e);
},
complete: () => {}
})
if (!socketTask) return
// console.log(socketTask);
printer.socketTask = socketTask
this.printMap.set(printServerIp, printer)
//监听开启
socketTask.onOpen(res => {
printer.isOpen = true
printer.isOpening = false
printer.reConnectCount = 0
uni.$emit('printStatus', {})
console.log(socketTask)
console.log(printServerIp + ': WebSocket连接成功。。。')
this.heartbeatStart(printer)
this.checkConnect(printer) //检测连接是否正常
})
//监听消息
socketTask.onMessage(res => {
printer.lastReceiveMessageTime = new Date().getTime()
let data = JSON.parse(res.data)
this.message(printer, data)
})
//监听关闭
socketTask.onClose(res => {
printer.isOpen = false
printer.isOpening = false
printer.socketTask = false
uni.$emit('printStatus', {})
// console.log(printer.printServerIp + ": WebSocket连接关闭。。。");
this.heartbeatClear(printer)
this.printMap.delete(printServerIp)
if (printer.reConnectCount <= 100) {
printer.reConnectCount += 1
this.reOpen(printer.printServerIp, printer.printServerPort)
}
})
//监听错误
socketTask.onError(res => {
printer.isOpen = false
printer.isOpening = false
printer.socketTask = false
uni.$emit('printStatus', {})
// console.log(printServerIp + ": WebSocket连接失败。。。");
// console.log(res);
this.heartbeatClear(printer)
this.printMap.delete(printServerIp)
if (printer.reConnectCount <= 100) {
printer.reConnectCount += 1
this.reOpen(printer.printServerIp, printer.printServerPort)
}
})
},
//重新打开
reOpen(printServerIp, printServerPort) {
this.timeoutID = setTimeout(() => {
// console.log("开始重连。。。");
this.open(printServerIp, printServerPort)
}, 5000)
},
//消息处理
message(printer, data) {
console.log(data)
switch (data.cmd) {
case 'heartbeat':
this.heartbeatReset(printer)
break
}
// switch (data.type){
// case "ycbm":
// console.log("一次编密");
// break;
// case "ecbm":
// console.log("二次编密");
// break;
// case "jmsy":
// console.log("简码收样");
// break;
// case "heartbeat":
// console.log("接收到心跳包回复:" + data.sampleCode);
// this.heartbeatReset(printer);
// break;
// }
},
//关闭连接
close(printServerIp) {
let printer = this.printMap.get(printServerIp)
if (!printer) return //不存在直接返回
if (printer.isOpen) {
printer.socketTask.close()
printer.isOpen = false
}
},
//发送消息
send(printServerIp, data) {
let printer = this.printMap.get(printServerIp)
if (!printer) {
//不存在则打开
this.open(printServerIp)
}
if (printer.socketTask) {
printer.socketTask.send({
data: data
})
}
},
//获取打印模板并执行打印
getPrintTemplateAndPrint(currentTask) {
const id = currentTask.taskTypeId
getConAssayTaskWithReportTemplateContent(id)
.then(res => {
this.print(currentTask, res)
})
.catch(err => {
console.log(err)
})
},
//调用send方法执行打印
print(currentTask, conAssayTask) {
const me = this
let id = currentTask.id
const reportTemplate = conAssayTask.reportTemplateDataContent
me.getReportData(id, function (res) {
const data = res.data || []
const reportData = {
data: data
}
let printData = {
// type: "preview",
type: 'print',
reportTemplate: reportTemplate,
reportData: JSON.stringify(reportData)
}
//连接打印服务
let printList = uni.getStorageSync('KEY_PRINT_LIST')
if (printList && printList.length > 0) {
let print = printList[0]
let printServerIp = print.printIp
me.send(printServerIp, JSON.stringify(printData))
}
})
},
//获取打印模板
getReportData(id, onComplete) {
const param = {
taskId: id,
hideResultFlag: 'true'
}
queryTaskDetailListByAssayTaskId(param).then(res => {
onComplete(res)
})
}
}

285
nx/helper/test.js Normal file
View File

@@ -0,0 +1,285 @@
/**
* 验证电子邮箱格式
*/
function email(value) {
return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value);
}
/**
* 验证手机格式
*/
function mobile(value) {
return /^1[23456789]\d{9}$/.test(value);
}
/**
* 验证URL格式
*/
function url(value) {
return /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/.test(
value,
);
}
/**
* 验证日期格式
*/
function date(value) {
if (!value) return false;
// 判断是否数值或者字符串数值(意味着为时间戳)转为数值否则new Date无法识别字符串时间戳
if (number(value)) value = +value;
return !/Invalid|NaN/.test(new Date(value).toString());
}
/**
* 验证ISO类型的日期格式
*/
function dateISO(value) {
return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value);
}
/**
* 验证十进制数字
*/
function number(value) {
return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value);
}
/**
* 验证字符串
*/
function string(value) {
return typeof value === 'string';
}
/**
* 验证整数
*/
function digits(value) {
return /^\d+$/.test(value);
}
/**
* 验证身份证号码
*/
function idCard(value) {
return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value);
}
/**
* 是否车牌号
*/
function carNo(value) {
// 新能源车牌
const xreg =
/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;
// 旧车牌
const creg =
/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;
if (value.length === 7) {
return creg.test(value);
}
if (value.length === 8) {
return xreg.test(value);
}
return false;
}
/**
* 金额,只允许2位小数
*/
function amount(value) {
// 金额,只允许保留两位小数
return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value);
}
/**
* 中文
*/
function chinese(value) {
const reg = /^[\u4e00-\u9fa5]+$/gi;
return reg.test(value);
}
/**
* 只能输入字母
*/
function letter(value) {
return /^[a-zA-Z]*$/.test(value);
}
/**
* 只能是字母或者数字
*/
function enOrNum(value) {
// 英文或者数字
const reg = /^[0-9a-zA-Z]*$/g;
return reg.test(value);
}
/**
* 验证是否包含某个值
*/
function contains(value, param) {
return value.indexOf(param) >= 0;
}
/**
* 验证一个值范围[min, max]
*/
function range(value, param) {
return value >= param[0] && value <= param[1];
}
/**
* 验证一个长度范围[min, max]
*/
function rangeLength(value, param) {
return value.length >= param[0] && value.length <= param[1];
}
/**
* 是否固定电话
*/
function landline(value) {
const reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/;
return reg.test(value);
}
/**
* 判断是否为空
*/
function empty(value) {
switch (typeof value) {
case 'undefined':
return true;
case 'string':
if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true;
break;
case 'boolean':
if (!value) return true;
break;
case 'number':
if (value === 0 || isNaN(value)) return true;
break;
case 'object':
if (value === null || value.length === 0) return true;
for (const i in value) {
return false;
}
return true;
}
return false;
}
/**
* 是否json字符串
*/
function jsonString(value) {
if (typeof value === 'string') {
try {
const obj = JSON.parse(value);
if (typeof obj === 'object' && obj) {
return true;
}
return false;
} catch (e) {
return false;
}
}
return false;
}
/**
* 是否数组
*/
function array(value) {
if (typeof Array.isArray === 'function') {
return Array.isArray(value);
}
return Object.prototype.toString.call(value) === '[object Array]';
}
/**
* 是否对象
*/
function object(value) {
return Object.prototype.toString.call(value) === '[object Object]';
}
/**
* 是否短信验证码
*/
function code(value, len = 6) {
return new RegExp(`^\\d{${len}}$`).test(value);
}
/**
* 是否函数方法
* @param {Object} value
*/
function func(value) {
return typeof value === 'function';
}
/**
* 是否promise对象
* @param {Object} value
*/
function promise(value) {
return object(value) && func(value.then) && func(value.catch);
}
/** 是否图片格式
* @param {Object} value
*/
function image(value) {
const newValue = value.split('?')[0];
const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i;
return IMAGE_REGEXP.test(newValue);
}
/**
* 是否视频格式
* @param {Object} value
*/
function video(value) {
const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i;
return VIDEO_REGEXP.test(value);
}
/**
* 是否为正则对象
* @param {Object}
* @return {Boolean}
*/
function regExp(o) {
return o && Object.prototype.toString.call(o) === '[object RegExp]';
}
export default {
email,
mobile,
url,
date,
dateISO,
number,
digits,
idCard,
carNo,
amount,
chinese,
letter,
enOrNum,
contains,
range,
rangeLength,
empty,
isEmpty: empty,
isNumber: number,
jsonString,
landline,
object,
array,
code,
};

43
nx/hooks/useGridCol.js Normal file
View File

@@ -0,0 +1,43 @@
import { ref, onMounted, onUnmounted } from 'vue'
import { debounce } from 'lodash' // 或手动实现防抖
/**
* 动态计算网格列数的 Hook
* @param {number[]} breakpoints - 断点数组,如 [400, 600] 表示 400px 和 600px 两个断点
* @param {number[]} cols - 对应断点的列数,如 [2, 3, 4] 表示:
* - 屏幕宽度 < 400px: 2 列
* - 400px ≤ 宽度 < 600px: 3 列
* - 宽度 ≥ 600px: 4 列
* @returns {Object} { gridCol } - 返回响应式的列数引用
*/
export function useGridCol(breakpoints = [400, 600], cols = [2, 3, 4]) {
const gridCol = ref(cols[cols.length - 1]) // 默认取最大值(大屏列数)
const calculateGridCol = () => {
const { windowWidth } = uni.getSystemInfoSync()
let selectedCol = cols[cols.length - 1] // 默认值
// 遍历断点,找到匹配的列数
for (let i = 0; i < breakpoints.length; i++) {
if (windowWidth < breakpoints[i]) {
selectedCol = cols[i]
break
}
}
gridCol.value = selectedCol
}
onMounted(() => {
calculateGridCol() // 初始化计算
uni.onWindowResize(calculateGridCol) // 监听窗口变化
})
onUnmounted(() => {
// 清理监听(部分平台可能需要手动实现)
if (typeof uni.offWindowResize === 'function') {
uni.offWindowResize(calculateGridCol)
}
})
return { gridCol }
}

View File

@@ -0,0 +1,88 @@
import { ref, reactive, onMounted, watch, unref } from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'
export function useListData({ searchParams, api, needInitListData = false, processData }) {
// 定义响应式数据
const initListData = ref(needInitListData)
const loadingData = ref(true)
const pageParams = reactive({
pageNo: 1,
pageSize: 10,
order: 'desc',
column: 'createTime'
})
const total = ref(0)
const loadStatus = ref('loadmore')
const listData = ref([])
// 模拟获取数据的方法
const getListData = async () => {
const params = {
...unref(searchParams),
...pageParams
}
let { records, total: pageTotal } = await api(params)
total.value = pageTotal
if (processData) {
records = processData(records)
}
return records
}
// 页面底部触底加载更多
const scrollToLower = async () => {
if (listData.value.length >= total.value) {
loadStatus.value = 'nomore'
return
} else {
loadStatus.value = 'loading'
}
pageParams.pageNo++
await loadMore()
}
// 加载更多数据
const loadMore = async () => {
const newData = await getListData()
listData.value = [...listData.value, ...newData]
if (listData.value.length >= total.value) loadStatus.value = 'nomore'
}
// 初始化数据
const getInitData = async () => {
loadStatus.value = 'loadmore'
pageParams.pageNo = 1
total.value = 0
listData.value = []
loadingData.value = true
let data = await getListData().finally(() => {
loadingData.value = false
})
listData.value = data
if (listData.value.length >= total.value) loadStatus.value = 'nomore'
}
// 组件挂载时执行初始化
onMounted(() => {
if (initListData.value) {
getInitData()
}
})
onReachBottom(() => {
scrollToLower()
})
// 监听滚动到底部事件
// 注意:在实际应用中,你需要根据你的框架或库来监听滚动到底部的事件
return {
initListData,
loadingData,
pageParams,
total,
loadStatus,
listData,
loadMore,
scrollToLower,
getInitData
}
}

View File

@@ -0,0 +1,46 @@
// useScreenOrientation.ts
import { onUnmounted } from 'vue'
//orientation:'portrait' | 'landscape'
export function useScreenOrientation() {
// 锁定屏幕方向
const lockOrientation = orientation => {
try {
if (typeof plus !== 'undefined' && plus.screen) {
const currentOrientation = plus.screen.orientation
if (currentOrientation !== orientation) {
plus.screen.lockOrientation(orientation)
return true
}
}
} catch (e) {
console.warn('锁定方向失败:', e)
return false
}
return false
}
// 解锁屏幕方向
const unlockOrientation = () => {
try {
if (typeof plus !== 'undefined' && plus.screen) {
plus.screen.unlockOrientation()
return true
}
} catch (e) {
console.warn('解锁方向失败:', e)
return false
}
return false
}
// 自动在组件卸载时解锁
onUnmounted(() => {
unlockOrientation()
})
return {
lockOrientation,
unlockOrientation
}
}

48
nx/index.js Normal file
View File

@@ -0,0 +1,48 @@
import $router from '@/nx/router'
import $helper from '@/nx/helper'
import $store from '@/nx/store'
import $measure from '@/nx/helper/measure'
import $print from '@/nx/helper/print'
import $api from '@/nx/api'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import duration from 'dayjs/plugin/duration'
import 'dayjs/locale/zh-cn'
dayjs.locale('zh-cn')
dayjs.extend(relativeTime)
dayjs.extend(duration)
const nx = {
$store,
$router,
$helper,
$measure,
$print,
$dayjs: dayjs,
$api
}
// 加载Nx底层依赖
export async function NxInit() {
if (process.env.NODE_ENV === 'development') {
NxDebug()
}
// #ifdef MP-WEIXIN
// 检测小程序更新
// wechat.checkMiniProgramUpdate()
// #endif
}
// 开发模式
function NxDebug() {
// 开发环境引入vconsole调试
// #ifdef H5
// import("vconsole").then(vconsole => {
// new vconsole.default();
// });
// #endif
}
export default nx

384
nx/request/index.js Normal file
View File

@@ -0,0 +1,384 @@
/**
* nx-request
* @description api模块管理loading配置请求拦截错误处理
*/
import Request from 'luch-request'
import { getBaseUrl, getTenantId } from '@/defaultBaseUrl'
import $store from '@/nx/store'
import { ApiEncryption } from '@/nx/utils/crypto.js'
const apiEncryption = new ApiEncryption()
const options = {
// 显示操作成功消息 默认不显示
showSuccess: false,
// 成功提醒 默认使用后端返回值
successMsg: '操作成功',
// 显示失败消息 默认显示
showError: true,
// 失败提醒 默认使用后端返回信息
errorMsg: '操作失败',
// 显示请求时loading模态框 默认显示
showLoading: true,
// loading提醒文字
loadingMsg: '加载中',
// 需要授权才能请求 默认放开
auth: false,
// 是否处理请求结果
isTransformResponse: true
}
const COMPANY_DEPT_RETRY_HEADER = '__companyDeptRetried'
const VISIT_COMPANY_STORAGE_KEY = 'visit-company-info'
const VISIT_DEPT_STORAGE_KEY = 'visit-dept-info'
// Loading全局实例
let LoadingInstance = {
target: null,
count: 0
}
/**
* 关闭loading
*/
function closeLoading() {
if (LoadingInstance.count > 0) LoadingInstance.count--
if (LoadingInstance.count === 0) uni.hideLoading()
}
/**
* @description 请求基础配置 可直接使用访问自定义请求
*/
const http = new Request({
timeout: 8000,
method: 'GET',
header: {
'Content-Type': 'application/json;charset=UTF-8'
},
// #ifdef APP-PLUS
sslVerify: false,
// #endif
// #ifdef H5
// 跨域请求时是否携带凭证cookies仅H5支持HBuilderX 2.6.15+
withCredentials: false,
// #endif
custom: options
})
/**
* @description 请求拦截器
*/
http.interceptors.request.use(
config => {
if (config.custom.showLoading) {
LoadingInstance.count++
LoadingInstance.count === 1 &&
uni.showLoading({
title: config.custom.loadingMsg,
mask: true,
fail: () => {
uni.hideLoading()
}
})
}
config.baseURL = getBaseUrl()
// 可使用async await 做异步操作
config.header['X-TIMESTAMP'] = new Date().getTime()
const token = getAccessToken()
if (token) config.header['Authorization'] = token
config.header['Accept'] = '*/*'
config.header['tenant-id'] = getTenantId()
let params = config.params || {}
let data = config.data || false
if (process.env.NODE_ENV == 'development') console.log('development--params', params)
if (process.env.NODE_ENV == 'development') console.log('development--data', data)
const visitCompanyId = getVisitCompanyId()
if (visitCompanyId !== undefined && visitCompanyId !== null && visitCompanyId !== '') {
config.header['visit-company-id'] = visitCompanyId
const visitCompanyName = getVisitCompanyName()
if (visitCompanyName !== undefined && visitCompanyName !== null) {
config.header['visit-company-name'] = encodeURIComponent(visitCompanyName || '')
}
}
const visitDeptId = getVisitDeptId()
if (visitDeptId !== undefined && visitDeptId !== null && visitDeptId !== '') {
config.header['visit-dept-id'] = visitDeptId
const visitDeptName = getVisitDeptName()
if (visitDeptName !== undefined && visitDeptName !== null) {
config.header['visit-dept-name'] = encodeURIComponent(visitDeptName || '')
}
}
return config
},
error => {
return Promise.reject(error)
}
)
/**
* @description 响应拦截器
*/
http.interceptors.response.use(
response => {
// 自动设置登陆令牌
// if (response.header.authorization || response.header.Authorization) {
// $store('user').setToken(response.header.authorization || response.header.Authorization)
// }
response.config.custom.showLoading && closeLoading()
console.log('response', JSON.parse(JSON.stringify(response.data)))
if (!response.config.custom.isTransformResponse) {
return Promise.resolve(response.data)
}
const { code, data, msg } = response.data
// 统一处理【公司/部门二次选择】:参考 PC 端逻辑,自动补全或提示选择后重试
if (code === 400 && Array.isArray(data)) {
debugger
const companyDeptList = data
const config = response.config
config.header = config.header || {}
if (companyDeptList.length === 1) {
const item = companyDeptList[0]
if (!config.header[COMPANY_DEPT_RETRY_HEADER]) {
applyCompanyDeptSelection(item, config)
return request(config)
}
uni.showToast({
title: '公司/部门信息缺失,且自动补全失败,请联系管理员',
icon: 'none',
mask: true
})
return Promise.resolve(data)
} else if (companyDeptList.length > 1) {
const groupedList = normalizeCompanyDeptList(companyDeptList)
const companyDeptDialogStore = $store('company-dept')
return new Promise(resolve => {
companyDeptDialogStore.open({
companyList: groupedList,
onConfirm: ({ companyId, deptId }) => {
const selectedCompany = groupedList.find(company => company.companyId === companyId)
const selectedDept = selectedCompany?.depts.find(dept => dept.deptId === deptId)
applyCompanyDeptSelection(
{
companyId,
companyName: selectedCompany?.companyName || '',
deptId,
deptName: selectedDept?.deptName || ''
},
config
)
resolve(request(config))
},
onCancel: () => {
uni.showToast({
title: '已取消公司/部门选择',
icon: 'none',
mask: true
})
resolve(data)
}
})
})
}
}
if (code !== 0) {
uni.showToast({
title: msg || response.config.custom.errorMsg,
icon: 'none'
})
}
if ((code === 0 || code === 200) && response.config.custom.showSuccess) {
setTimeout(() => {
uni.showToast({
title: msg || response.config.custom.successMsg,
icon: 'none'
})
}, 100)
}
$store('user').updateLastRequestTime()
return Promise.resolve(data)
},
error => {
console.log('error', error)
const userStore = $store('user')
const isLogin = userStore.isLogin
let errorMessage = '网络请求出错'
if (error !== undefined) {
switch (error.statusCode) {
case 400:
errorMessage = '请求错误'
break
case 401:
if (isLogin) {
errorMessage = '您的登陆已过期'
} else {
errorMessage = '请先登录'
}
userStore.logout(true)
break
case 403:
errorMessage = '拒绝访问'
break
case 404:
errorMessage = '请求出错'
break
case 408:
errorMessage = '请求超时'
break
case 429:
errorMessage = '请求频繁, 请稍后再访问'
break
case 500:
errorMessage = '服务器开小差啦,请稍后再试~'
break
case 501:
errorMessage = '服务未实现'
break
case 502:
errorMessage = '网络错误'
break
case 503:
errorMessage = '服务不可用'
break
case 504:
errorMessage = '网络超时'
break
case 505:
errorMessage = 'HTTP版本不受支持'
break
}
if (error.errMsg.includes('timeout')) errorMessage = '请求超时'
// #ifdef H5
if (error.errMsg.includes('Network')) errorMessage = window.navigator.onLine ? '服务器异常' : '请检查您的网络连接'
// #endif
}
if (error && error.config) {
if (error.config.custom.showError === true) {
uni.showToast({
title: error.data?.msg || errorMessage,
icon: 'none',
mask: true
})
}
error.config.custom.showLoading && closeLoading()
}
return Promise.reject(error)
}
)
/** 获得访问令牌 */
export const getAccessToken = () => {
return uni.getStorageSync('token')
}
const getStorageObject = key => {
const value = uni.getStorageSync(key)
if (!value) {
return {}
}
if (typeof value === 'string') {
try {
return JSON.parse(value)
} catch (error) {
console.warn(`解析本地存储 ${key} 失败:`, error)
return {}
}
}
return value
}
const setStorageObject = (key, value) => {
if (value === undefined || value === null) {
uni.removeStorageSync(key)
return
}
uni.setStorageSync(key, value)
}
export const getVisitCompanyId = () => {
const info = getStorageObject(VISIT_COMPANY_STORAGE_KEY)
return info?.id ?? info?.companyId ?? null
}
export const getVisitCompanyName = () => {
const info = getStorageObject(VISIT_COMPANY_STORAGE_KEY)
return info?.name ?? info?.companyName ?? ''
}
export const getVisitDeptId = () => {
const info = getStorageObject(VISIT_DEPT_STORAGE_KEY)
return info?.id ?? info?.deptId ?? null
}
export const getVisitDeptName = () => {
const info = getStorageObject(VISIT_DEPT_STORAGE_KEY)
return info?.name ?? info?.deptName ?? ''
}
export const setVisitCompany = (companyId, companyName) => {
if (companyId === undefined || companyId === null || companyId === '') {
uni.removeStorageSync(VISIT_COMPANY_STORAGE_KEY)
return
}
setStorageObject(VISIT_COMPANY_STORAGE_KEY, {
id: companyId,
name: companyName || ''
})
}
export const setVisitDept = (deptId, deptName) => {
if (deptId === undefined || deptId === null || deptId === '') {
uni.removeStorageSync(VISIT_DEPT_STORAGE_KEY)
return
}
setStorageObject(VISIT_DEPT_STORAGE_KEY, {
id: deptId,
name: deptName || ''
})
}
const applyCompanyDeptSelection = (item, config) => {
setVisitCompany(item.companyId, item.companyName)
setVisitDept(item.deptId, item.deptName)
config.header['visit-company-id'] = item.companyId
config.header['visit-company-name'] = encodeURIComponent(item.companyName || '')
config.header['visit-dept-id'] = item.deptId
config.header['visit-dept-name'] = encodeURIComponent(item.deptName || '')
config.header[COMPANY_DEPT_RETRY_HEADER] = '1'
}
const normalizeCompanyDeptList = (list = []) => {
const companyMap = new Map()
list.forEach(item => {
if (!companyMap.has(item.companyId)) {
companyMap.set(item.companyId, {
companyId: item.companyId,
companyName: item.companyName,
depts: []
})
}
const company = companyMap.get(item.companyId)
if (!company.depts.some(dept => dept.deptId === item.deptId)) {
company.depts.push({
deptId: item.deptId,
deptName: item.deptName
})
}
})
return Array.from(companyMap.values())
}
const request = config => {
return http.middleware(config)
}
export default request

187
nx/router/index.js Normal file
View File

@@ -0,0 +1,187 @@
import $store from '@/nx/store'
import { isString, isEmpty, startsWith, isObject, isNil, clone } from 'lodash'
import { throttle } from '@/uview-plus'
const _go = (
path,
params = {},
options = {
redirect: false,
reLaunch: false
}
) => {
let page = '' // 跳转页面
let query = '' // 页面参数
let url = '' // 跳转页面完整路径
if (isString(path)) {
// 判断跳转类型是 path 还是http
if (startsWith(path, 'http')) {
// #ifdef H5
window.location = path
return
// #endif
// #ifndef H5
page = `/pages/public/webview`
query = `url=${encodeURIComponent(path)}`
// #endif
} else {
;[page, query] = path.split('?')
}
if (!isEmpty(params)) {
let query2 = paramsToQuery(params)
if (isEmpty(query)) {
query = query2
} else {
query += '&' + query2
}
}
}
if (isObject(path)) {
page = path.url
if (!isNil(path.params)) {
query = paramsToQuery(path.params)
}
}
const nextRoute = ROUTES_MAP[page]
// 未找到指定跳转页面
// mark: 跳转404页
if (!nextRoute) {
console.log(`%c跳转路径参数错误<${page || 'EMPTY'}>`, 'color:red;background:yellow')
return
}
// 页面登录拦截
if (nextRoute.meta?.auth && !$store('user').isLogin) {
// 这里做未登录拦截
uni.reLaunch({
url: 'pages/login/login'
})
return
}
url = page
if (!isEmpty(query)) {
url += `?${query}`
}
// 跳转底部导航
if (TABBAR.includes(page)) {
uni.switchTab({
url
})
return
}
// 使用redirect跳转
if (options.redirect) {
uni.redirectTo({
url
})
return
}
if (options.reLaunch) {
uni.reLaunch({
url
})
return
}
uni.navigateTo({
url
})
}
// 限流 防止重复点击跳转
function go(...args) {
throttle(_go(...args), 500)
}
function paramsToQuery(params) {
if (isEmpty(params)) {
return ''
}
// return new URLSearchParams(Object.entries(params)).toString();
let query = []
for (let key in params) {
query.push(key + '=' + params[key])
}
return query.join('&')
}
function back() {
// #ifdef H5
history.back()
// #endif
// #ifndef H5
uni.navigateBack()
// #endif
}
function redirect(path, params = {}) {
go(path, params, {
redirect: true
})
}
// 检测是否有浏览器历史
function hasHistory() {
// #ifndef H5
const pages = getCurrentPages()
if (pages.length > 1) {
return true
}
return false
// #endif
// #ifdef H5
return !!history.state.back
// #endif
}
function getCurrentRoute(field = '') {
let currentPage = getCurrentPage()
// #ifdef MP
currentPage.$page['route'] = currentPage.route
currentPage.$page['options'] = currentPage.options
// #endif
if (field !== '') {
return currentPage.$page[field]
} else {
return currentPage.$page
}
}
function getCurrentPage() {
let pages = getCurrentPages()
return pages[pages.length - 1]
}
function getCur() {
let a = getCurrentPages()
let pages = clone(a)
return pages
}
function error(errCode, errMsg = '') {
redirect('/pages/public/error', {
errCode,
errMsg
})
}
export default {
go,
back,
hasHistory,
redirect,
getCurrentPage,
getCurrentRoute,
getCur,
error
}

View File

@@ -0,0 +1,79 @@
const singleComment = Symbol('singleComment');
const multiComment = Symbol('multiComment');
const stripWithoutWhitespace = () => '';
const stripWithWhitespace = (string, start, end) => string.slice(start, end).replace(/\S/g, ' ');
const isEscaped = (jsonString, quotePosition) => {
let index = quotePosition - 1;
let backslashCount = 0;
while (jsonString[index] === '\\') {
index -= 1;
backslashCount += 1;
}
return Boolean(backslashCount % 2);
};
export default function stripJsonComments(jsonString, { whitespace = true } = {}) {
if (typeof jsonString !== 'string') {
throw new TypeError(
`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof jsonString}\``,
);
}
const strip = whitespace ? stripWithWhitespace : stripWithoutWhitespace;
let isInsideString = false;
let isInsideComment = false;
let offset = 0;
let result = '';
for (let index = 0; index < jsonString.length; index++) {
const currentCharacter = jsonString[index];
const nextCharacter = jsonString[index + 1];
if (!isInsideComment && currentCharacter === '"') {
const escaped = isEscaped(jsonString, index);
if (!escaped) {
isInsideString = !isInsideString;
}
}
if (isInsideString) {
continue;
}
if (!isInsideComment && currentCharacter + nextCharacter === '//') {
result += jsonString.slice(offset, index);
offset = index;
isInsideComment = singleComment;
index++;
} else if (isInsideComment === singleComment && currentCharacter + nextCharacter === '\r\n') {
index++;
isInsideComment = false;
result += strip(jsonString, offset, index);
offset = index;
continue;
} else if (isInsideComment === singleComment && currentCharacter === '\n') {
isInsideComment = false;
result += strip(jsonString, offset, index);
offset = index;
} else if (!isInsideComment && currentCharacter + nextCharacter === '/*') {
result += jsonString.slice(offset, index);
offset = index;
isInsideComment = multiComment;
index++;
continue;
} else if (isInsideComment === multiComment && currentCharacter + nextCharacter === '*/') {
index++;
isInsideComment = false;
result += strip(jsonString, offset, index + 1);
offset = index + 1;
continue;
}
}
return result + (isInsideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset));
}

View File

@@ -0,0 +1,103 @@
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true,
});
const fs = require('fs');
import stripJsonComments from './strip-json-comments';
import { isArray, isEmpty } from 'lodash';
class TransformPages {
constructor({ includes, pagesJsonDir }) {
this.includes = includes;
this.uniPagesJSON = JSON.parse(stripJsonComments(fs.readFileSync(pagesJsonDir, 'utf-8')));
this.routes = this.getPagesRoutes().concat(this.getSubPackagesRoutes());
this.tabbar = this.getTabbarRoutes();
this.routesMap = this.transformPathToKey(this.routes);
}
/**
* 通过读取pages.json文件 生成直接可用的routes
*/
getPagesRoutes(pages = this.uniPagesJSON.pages, rootPath = null) {
let routes = [];
for (let i = 0; i < pages.length; i++) {
const item = pages[i];
let route = {};
for (let j = 0; j < this.includes.length; j++) {
const key = this.includes[j];
let value = item[key];
if (key === 'path') {
value = rootPath ? `/${rootPath}/${value}` : `/${value}`;
}
if (key === 'aliasPath' && i == 0 && rootPath == null) {
route[key] = route[key] || '/';
} else if (value !== undefined) {
route[key] = value;
}
}
routes.push(route);
}
return routes;
}
/**
* 解析小程序分包路径
*/
getSubPackagesRoutes() {
if (!(this.uniPagesJSON && this.uniPagesJSON.subPackages)) {
return [];
}
const subPackages = this.uniPagesJSON.subPackages;
let routes = [];
for (let i = 0; i < subPackages.length; i++) {
const subPages = subPackages[i].pages;
const root = subPackages[i].root;
const subRoutes = this.getPagesRoutes(subPages, root);
routes = routes.concat(subRoutes);
}
return routes;
}
getTabbarRoutes() {
if (!(this.uniPagesJSON && this.uniPagesJSON.tabBar && this.uniPagesJSON.tabBar.list)) {
return [];
}
const tabbar = this.uniPagesJSON.tabBar.list;
let tabbarMap = [];
tabbar.forEach((bar) => {
tabbarMap.push('/' + bar.pagePath);
});
return tabbarMap;
}
transformPathToKey(list) {
if (!isArray(list) || isEmpty(list)) {
return [];
}
let map = {};
list.forEach((i) => {
map[i.path] = i;
});
return map;
}
}
function uniReadPagesV3Plugin({ pagesJsonDir, includes }) {
let defaultIncludes = ['path', 'aliasPath', 'name'];
includes = [...defaultIncludes, ...includes];
let pages = new TransformPages({
pagesJsonDir,
includes,
});
return {
name: 'uni-read-pages-v3',
config(config) {
return {
define: {
ROUTES: pages.routes,
ROUTES_MAP: pages.routesMap,
TABBAR: pages.tabbar,
},
};
},
};
}
exports.default = uniReadPagesV3Plugin;

177
nx/scss/index.scss Normal file
View File

@@ -0,0 +1,177 @@
page {
-webkit-overflow-scrolling: touch; // 解决ios滑动不流畅
height: 100%;
width: 100%;
word-break: break-all; //英文文本不换行
white-space: normal;
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
display: none;
}
.full-page{
// height: 100%;
// width: 100%;
// background-color: #f0f2f5;
// box-sizing: border-box;
// padding: 10px;
// font-size: 14px;
}
/*flex布局(colorui里面也有相关基础样式)*/
/* x水平排列*/
.x-f {
display: flex;
align-items: center;
}
/*x两端且水平居中*/
.x-bc {
display: flex;
justify-content: space-between;
align-items: center;
}
/*x平分且水平居中*/
.x-ac {
display: flex;
justify-content: space-around;
align-items: center;
}
/*x水平靠上对齐*/
.x-start {
display: flex;
align-items: flex-start;
}
/*x水平靠下对齐*/
.x-end {
display: flex;
align-items: flex-end;
}
/*上下左右居中*/
.x-c {
display: flex;
justify-content: center;
align-items: center;
}
/*y竖直靠左*/
.y-start {
display: flex;
flex-direction: column;
align-items: flex-start;
}
/*y竖直靠右*/
.y-end {
display: flex;
flex-direction: column;
align-items: flex-end;
}
/*y竖直居中*/
.y-f {
display: flex;
flex-direction: column;
align-items: center;
}
/* y竖直两端*/
.y-b {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.y-a {
display: flex;
flex-direction: column;
justify-content: space-around;
}
/*y竖直两端居中*/
.y-bc {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.flex1{
flex:1;
}
.flex-wrap{
flex-wrap:wrap ;
}
// 颜色
.white{
color:#fff ;
}
.bg-w{
background-color: #fff;
}
// height,width
.full-width{
width: 100%;
}
.full-height{
height: 100%;
}
.text-center{
text-align: center;
}
.text-left{
text-align: left;
}
.text-right{
text-align: right;
}
// 字体
@for $i from 12 through 64 {
.fs#{$i} {
font-size: #{$i}px;
}
}
/* 外边距、内边距全局样式 */
@for $i from 0 through 100 {
.m#{$i} {
margin: #{$i}px;
}
.mt#{$i} {
margin-top: #{$i}px;
}
.mr#{$i} {
margin-right: #{$i}px;
}
.mb#{$i} {
margin-bottom: #{$i}px;
}
.ml#{$i} {
margin-left: #{$i}px;
}
.p#{$i} {
padding: #{$i}px;
}
.pt#{$i} {
padding-top: #{$i}px;
}
.pr#{$i} {
padding-right: #{$i}px;
}
.pb#{$i} {
padding-bottom: #{$i}px;
}
.pl#{$i} {
padding-left: #{$i}px;
}
}
// font-weight
.font-bold{
font-weight:bold
}
.border-b{
border-bottom: 2px solid rgba(#707070,0.11);
}

17
nx/store/biz.js Normal file
View File

@@ -0,0 +1,17 @@
import { defineStore } from 'pinia'
import nx from '@/nx'
const biz = defineStore({
id: 'biz',
state: () => ({
deviceInfo: {},
scanQRInfo: null,
}),
actions: {
}
})
export default biz

66
nx/store/company-dept.js Normal file
View File

@@ -0,0 +1,66 @@
import { defineStore } from 'pinia';
const defaultState = () => ({
show: false,
title: '请选择当前业务办理归属的公司部门信息',
companyList: [],
selectedCompanyId: null,
selectedDeptId: null,
onConfirm: null,
onCancel: null,
});
const companyDeptStore = defineStore({
id: 'company-dept',
state: defaultState,
actions: {
open({ companyList = [], onConfirm = null, onCancel = null, defaultCompanyId = null, defaultDeptId = null, title = null }) {
this.companyList = companyList;
this.onConfirm = onConfirm;
this.onCancel = onCancel;
this.title = title || '请选择当前业务办理归属的公司部门信息';
this.show = true;
this.selectedCompanyId = defaultCompanyId;
this.selectedDeptId = defaultDeptId;
if (!this.selectedCompanyId && this.companyList.length > 0) {
this.selectedCompanyId = this.companyList[0].companyId;
}
if (!this.selectedDeptId) {
const depts = this.getDeptsByCompanyId(this.selectedCompanyId);
this.selectedDeptId = depts.length > 0 ? depts[0].deptId : null;
}
},
close() {
Object.assign(this, defaultState());
},
getDeptsByCompanyId(companyId) {
const company = this.companyList.find((item) => item.companyId === companyId);
return company?.depts || [];
},
setSelectedCompany(companyId) {
this.selectedCompanyId = companyId;
const depts = this.getDeptsByCompanyId(companyId);
const currentDeptIds = depts.map((dept) => dept.deptId);
if (!currentDeptIds.includes(this.selectedDeptId)) {
this.selectedDeptId = depts.length > 0 ? depts[0].deptId : null;
}
},
setSelectedDept(deptId) {
this.selectedDeptId = deptId;
},
confirm() {
if (this.onConfirm) {
this.onConfirm({ companyId: this.selectedCompanyId, deptId: this.selectedDeptId });
}
this.close();
},
cancel() {
if (this.onCancel) {
this.onCancel();
}
this.close();
},
},
});
export default companyDeptStore;

20
nx/store/index.js Normal file
View File

@@ -0,0 +1,20 @@
import { createPinia } from 'pinia';
import piniaPersist from 'pinia-plugin-persist-uni';
// 自动注入所有pinia模块
const files = import.meta.glob('./*.js', { eager: true });
const modules = {};
Object.keys(files).forEach((key) => {
modules[key.replace(/(.*\/)*([^.]+).*/gi, '$2')] = files[key].default;
});
export const setupPinia = (app) => {
const pinia = createPinia();
pinia.use(piniaPersist);
app.use(pinia);
};
export default (name) => {
return modules[name]();
};

127
nx/store/user.js Normal file
View File

@@ -0,0 +1,127 @@
import { defineStore } from 'pinia'
import userApi from '@/nx/api/user'
import { getSysParameterBizByName } from '@/nx/api/sys'
import md5 from 'md5'
import nx from '@/nx'
// 默认用户信息
const defaultUserInfo = {
avatar: '', // 头像
nickname: '', // 昵称
gender: 0, // 性别
mobile: '' // 手机号
}
const user = defineStore({
id: 'user',
state: () => ({
userInfo: uni.getStorageSync('userInfo') || { ...defaultUserInfo }, // 用户信息
token: uni.getStorageSync('token') || '',
isLogin: !!uni.getStorageSync('token'), // 登录状态
roleMenus: uni.getStorageSync('roleMenus') || [],
timeout: 10 * 60 * 1000,
lastRequestTime: null,
timeoutInterval: null
}),
actions: {
// 更新最后请求时间
updateLastRequestTime() {
this.lastRequestTime = Date.now()
},
// 检查是否超时
checkTimeout() {
if (!this.token || !this.lastRequestTime) return false
const currentTime = Date.now()
const elapsed = currentTime - this.lastRequestTime
if (this.timeout > 0 && elapsed > this.timeout) {
uni.showToast({
icon: 'none',
title: '登录超时,请重新登录'
})
this.logout()
return true
}
return false
},
startTimeoutChecker(interval = 60 * 1000) {
this.stopTimeoutChecker()
this.timeoutInterval = setInterval(() => {
this.checkTimeout()
}, interval)
},
stopTimeoutChecker() {
if (this.timeoutInterval) {
clearInterval(this.timeoutInterval)
this.timeoutInterval = null
}
},
async getDeviceTimeout() {
const result = await getSysParameterBizByName('lims_pda_timeout')
this.timeout = Number(result.dictValue) * 60 * 1000
},
async login(loginInfo) {
const info = await userApi.accountLogin(loginInfo)
if (info) {
this.setToken(info.accessToken)
await this.getUserInfo()
uni.showToast({
icon: 'success',
title: '登录成功'
})
// await this.getRoleMenus()
// await this.getDeviceTimeout()
// this.startTimeoutChecker()
uni.reLaunch({
url: '/pages/index/index'
})
}
},
async getUserInfo() {
const { user } = await userApi.getInfo()
if (user) {
this.userInfo = user
uni.setStorageSync('userInfo', this.userInfo)
}
},
async getRoleMenus() {
let params = {
parentNodeUrl: '/lims/mobile'
}
const result = await userApi.getRoleMenusByParentMenuKey(params)
if (result.length > 0) {
this.roleMenus = result.map(item => ({ url: item.url, name: item.name, icon: item.otherConf }))
uni.setStorageSync('roleMenus', this.roleMenus)
}
},
// 设置token
setToken(token = '') {
this.token = token
if (token === '') {
this.isLogin = false
uni.removeStorageSync('token')
} else {
this.isLogin = true
uni.setStorageSync('token', token)
}
return this.isLogin
},
// 登出
async logout() {
this.stopTimeoutChecker()
this.clearUserInfo()
uni.reLaunch({
url: '/pages/login/login'
})
},
clearUserInfo() {
this.userInfo = {}
this.roleMenus = []
uni.setStorageSync('roleMenus', [])
this.setToken()
}
}
})
export default user

235
nx/utils/base64.js Normal file
View File

@@ -0,0 +1,235 @@
/*
* base64.js
*
* Licensed under the BSD 3-Clause License.
* http://opensource.org/licenses/BSD-3-Clause
*
* References:
* http://en.wikipedia.org/wiki/Base64
*/
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? module.exports = factory(global)
: typeof define === 'function' && define.amd
? define(factory) : factory(global)
}((
typeof self !== 'undefined' ? self
: typeof window !== 'undefined' ? window
: typeof global !== 'undefined' ? global
: this
), function(global) {
'use strict';
// existing version for noConflict()
global = global || {};
var _Base64 = global.Base64;
var version = "2.5.1";
// if node.js and NOT React Native, we use Buffer
var buffer;
if (typeof module !== 'undefined' && module.exports) {
try {
buffer = eval("require('buffer').Buffer");
} catch (err) {
buffer = undefined;
}
}
// constants
var b64chars
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var b64tab = function(bin) {
var t = {};
for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
return t;
}(b64chars);
var fromCharCode = String.fromCharCode;
// encoder stuff
var cb_utob = function(c) {
if (c.length < 2) {
var cc = c.charCodeAt(0);
return cc < 0x80 ? c
: cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))
+ fromCharCode(0x80 | (cc & 0x3f)))
: (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))
+ fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
+ fromCharCode(0x80 | ( cc & 0x3f)));
} else {
var cc = 0x10000
+ (c.charCodeAt(0) - 0xD800) * 0x400
+ (c.charCodeAt(1) - 0xDC00);
return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))
+ fromCharCode(0x80 | ((cc >>> 12) & 0x3f))
+ fromCharCode(0x80 | ((cc >>> 6) & 0x3f))
+ fromCharCode(0x80 | ( cc & 0x3f)));
}
};
var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
var utob = function(u) {
return u.replace(re_utob, cb_utob);
};
var cb_encode = function(ccc) {
var padlen = [0, 2, 1][ccc.length % 3],
ord = ccc.charCodeAt(0) << 16
| ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)
| ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),
chars = [
b64chars.charAt( ord >>> 18),
b64chars.charAt((ord >>> 12) & 63),
padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),
padlen >= 1 ? '=' : b64chars.charAt(ord & 63)
];
return chars.join('');
};
var btoa = global.btoa ? function(b) {
return global.btoa(b);
} : function(b) {
return b.replace(/[\s\S]{1,3}/g, cb_encode);
};
var _encode = buffer ?
buffer.from && Uint8Array && buffer.from !== Uint8Array.from
? function (u) {
return (u.constructor === buffer.constructor ? u : buffer.from(u))
.toString('base64')
}
: function (u) {
return (u.constructor === buffer.constructor ? u : new buffer(u))
.toString('base64')
}
: function (u) { return btoa(utob(u)) }
;
var encode = function(u, urisafe) {
return !urisafe
? _encode(String(u))
: _encode(String(u)).replace(/[+\/]/g, function(m0) {
return m0 == '+' ? '-' : '_';
}).replace(/=/g, '');
};
var encodeURI = function(u) { return encode(u, true) };
// decoder stuff
var re_btou = new RegExp([
'[\xC0-\xDF][\x80-\xBF]',
'[\xE0-\xEF][\x80-\xBF]{2}',
'[\xF0-\xF7][\x80-\xBF]{3}'
].join('|'), 'g');
var cb_btou = function(cccc) {
switch(cccc.length) {
case 4:
var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
| ((0x3f & cccc.charCodeAt(1)) << 12)
| ((0x3f & cccc.charCodeAt(2)) << 6)
| (0x3f & cccc.charCodeAt(3)),
offset = cp - 0x10000;
return (fromCharCode((offset >>> 10) + 0xD800)
+ fromCharCode((offset & 0x3FF) + 0xDC00));
case 3:
return fromCharCode(
((0x0f & cccc.charCodeAt(0)) << 12)
| ((0x3f & cccc.charCodeAt(1)) << 6)
| (0x3f & cccc.charCodeAt(2))
);
default:
return fromCharCode(
((0x1f & cccc.charCodeAt(0)) << 6)
| (0x3f & cccc.charCodeAt(1))
);
}
};
var btou = function(b) {
return b.replace(re_btou, cb_btou);
};
var cb_decode = function(cccc) {
var len = cccc.length,
padlen = len % 4,
n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)
| (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)
| (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0)
| (len > 3 ? b64tab[cccc.charAt(3)] : 0),
chars = [
fromCharCode( n >>> 16),
fromCharCode((n >>> 8) & 0xff),
fromCharCode( n & 0xff)
];
chars.length -= [0, 0, 2, 1][padlen];
return chars.join('');
};
var _atob = global.atob ? function(a) {
return global.atob(a);
} : function(a){
return a.replace(/\S{1,4}/g, cb_decode);
};
var atob = function(a) {
return _atob(String(a).replace(/[^A-Za-z0-9\+\/]/g, ''));
};
var _decode = buffer ?
buffer.from && Uint8Array && buffer.from !== Uint8Array.from
? function(a) {
return (a.constructor === buffer.constructor
? a : buffer.from(a, 'base64')).toString();
}
: function(a) {
return (a.constructor === buffer.constructor
? a : new buffer(a, 'base64')).toString();
}
: function(a) { return btou(_atob(a)) };
var decode = function(a){
return _decode(
String(a).replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' })
.replace(/[^A-Za-z0-9\+\/]/g, '')
);
};
var noConflict = function() {
var Base64 = global.Base64;
global.Base64 = _Base64;
return Base64;
};
// export Base64
global.Base64 = {
VERSION: version,
atob: atob,
btoa: btoa,
fromBase64: decode,
toBase64: encode,
utob: utob,
encode: encode,
encodeURI: encodeURI,
btou: btou,
decode: decode,
noConflict: noConflict,
__buffer__: buffer
};
// if ES5 is available, make Base64.extendString() available
if (typeof Object.defineProperty === 'function') {
var noEnum = function(v){
return {value:v,enumerable:false,writable:true,configurable:true};
};
global.Base64.extendString = function () {
Object.defineProperty(
String.prototype, 'fromBase64', noEnum(function () {
return decode(this)
}));
Object.defineProperty(
String.prototype, 'toBase64', noEnum(function (urisafe) {
return encode(this, urisafe)
}));
Object.defineProperty(
String.prototype, 'toBase64URI', noEnum(function () {
return encode(this, true)
}));
};
}
//
// export Base64 to the namespace
//
if (global['Meteor']) { // Meteor.js
Base64 = global.Base64;
}
// module.exports and AMD are mutually exclusive.
// module.exports has precedence.
if (typeof module !== 'undefined' && module.exports) {
module.exports.Base64 = global.Base64;
}
else if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], function(){ return global.Base64 });
}
// that's it!
return {Base64: global.Base64}
}));

View File

@@ -0,0 +1,62 @@
import { getUpgradeBaseUrl, getTenantId, clientId } from '@/defaultBaseUrl'
export default function () {
// #ifdef APP-PLUS
return new Promise((resolve, reject) => {
plus.runtime.getProperty(plus.runtime.appid, function (widgetInfo) {
const osName = plus.os.name
let appId = plus.runtime.appid
appId = clientId
uni.request({
url:
getUpgradeBaseUrl() +
'/api/sys/app-client-version/latestVersionUniapp?clientId=' +
appId +
'&platform=' +
osName +
'&tenantId=' +
getTenantId(),
method: 'GET',
success: res => {
if (res.data && res.data.result) {
res.data.result.localVersion = plus.runtime.version
res.data.result.localWgtVersion = widgetInfo.version
res.data.result.url = getUpgradeBaseUrl() + res.data.result.url
}
console.log('更新信息:', res.data)
resolve(res.data)
},
fail: err => {
reject(error)
}
})
// uni.request(options).then(res => {
// resolve(res)
// }).catch(err => {
// reject(error)
// });
// uniCloud.callFunction({
// name: 'check-version',
// data: {
// appid: plus.runtime.appid,
// appVersion: plus.runtime.version,
// wgtVersion: widgetInfo.version
// },
// success: (e) => {
// resolve(e)
// },
// fail: (error) => {
// reject(error)
// }
// })
})
})
// #endif
// #ifndef APP-PLUS
return new Promise((resolve, reject) => {
reject({
message: '请在App中使用'
})
})
// #endif
}

244
nx/utils/check-update.js Normal file
View File

@@ -0,0 +1,244 @@
import callCheckVersion from './call-check-version'
// 推荐再App.vue中使用
const PACKAGE_INFO_KEY = '__package_info__'
export default function(isShowNoUpdateToast = false) {
// #ifdef APP-PLUS
return new Promise((resolve, reject) => {
callCheckVersion().then(async (e) => {
if (!e.result) return;
const {
code,
message,
is_silently, // 是否静默更新
url, // 安装包下载地址
platform, // 安装包平台
type // 安装包类型
} = e.result;
// 此处逻辑仅为实例,可自行编写
if (code > 0 && isUpdate(e.result)) {
console.log("更新逻辑。。。")
// 腾讯云和阿里云下载链接不同,需要处理一下,阿里云会原样返回
/**
const {
fileList
} = await uniCloud.getTempFileURL({
fileList: [url]
});
if (fileList[0].tempFileURL)
e.result.url = fileList[0].tempFileURL;
resolve(e)
**/
// 静默更新只有wgt有
if (is_silently) {
uni.downloadFile({
url: e.result.url,
success: res => {
if (res.statusCode == 200) {
// 下载好直接安装,下次启动生效
plus.runtime.install(res.tempFilePath, {
force: false
});
}
}
});
return;
}
/**
* 提示升级一
* 使用 uni.showModal
*/
// return updateUseModal(e.result)
/**
* 提示升级二
* 官方适配的升级弹窗可自行替换资源适配UI风格
*/
uni.setStorageSync(PACKAGE_INFO_KEY, e.result)
uni.navigateTo({
url: `/pages/setting/upgrade-popup?local_storage_key=${PACKAGE_INFO_KEY}`,
fail: (err) => {
console.error('更新弹框跳转失败', err)
uni.removeStorageSync(PACKAGE_INFO_KEY)
}
})
} else {
if(isShowNoUpdateToast) {
uni.showToast({
icon:'none',
title:"当前已是最新版本!"
});
uni.hideLoading();
}
}
if (code < 0) {
// TODO 云函数报错处理
console.error(message)
reject(e)
}
}).catch(err => {
// TODO 云函数报错处理
console.error(err.message)
reject(err)
})
});
// #endif
}
/**
* 使用 uni.showModal 升级
*/
function updateUseModal(packageInfo) {
const {
title, // 标题
contents, // 升级内容
is_mandatory, // 是否强制更新
url, // 安装包下载地址
platform, // 安装包平台
type // 安装包类型
} = packageInfo;
let isWGT = type === 'wgt'
let isiOS = !isWGT ? platform.includes('iOS') : false;
let confirmText = isiOS ? '立即跳转更新' : '立即下载更新'
return uni.showModal({
title,
content: contents,
showCancel: !is_mandatory,
confirmText,
success: res => {
if (res.cancel) return;
// 安装包下载
if (isiOS) {
plus.runtime.openURL(url);
return;
}
uni.showToast({
title: '后台下载中……',
duration: 1000
});
// wgt 和 安卓下载更新
downloadTask = uni.downloadFile({
url,
success: res => {
if (res.statusCode !== 200) {
console.error('下载安装包失败', err);
return;
}
// 下载好直接安装,下次启动生效
plus.runtime.install(res.tempFilePath, {
force: false
}, () => {
if (is_mandatory) {
//更新完重启app
plus.runtime.restart();
return;
}
uni.showModal({
title: '安装成功是否重启?',
success: res => {
if (res.confirm) {
//更新完重启app
plus.runtime.restart();
}
}
});
}, err => {
uni.showModal({
title: '更新失败',
content: err
.message,
showCancel: false
});
});
}
});
}
});
}
/**
*
*/
function isUpdate(packageInfo) {
let isUpdate = false;
const {
type, // 安装包类型
version, //版本
min_uni_version, //最低原生版本
localVersion,//本地版本
localWgtVersion //本地wgtVersion
} = packageInfo;
let isWGT = type === 'wgt';
// console.log("更新类型:" + type);
// console.log("服务器版本:" + version);
// console.log("wgt更新需要原生最低版本" + min_uni_version);
// console.log("本地版本:" + localVersion);
// console.log("本地wgt版本" + localWgtVersion);
if(isWGT) {
//wgt更新服务器版本必须大于本地wgt版本并且本地版本必须大于最低原生版本
// console.log("服务器版本与本地wgt版本比较" + compare(version, localWgtVersion));
// console.log("本地版本与服务器原生最低需要版本比较:" + compare(localVersion, min_uni_version));
// console.log((compare(version, localWgtVersion) == 1));
// console.log(compare(localVersion, min_uni_version) != -1)
isUpdate = (compare(version, localWgtVersion) == 1) && (compare(localVersion, min_uni_version) != -1);
} else {
isUpdate = compare(version, localVersion) == 1;
}
// console.log("是否需要更新:" + isUpdate);
return isUpdate;
}
/**
* 对比版本号,如需要,请自行修改判断规则
* 支持比对 ("3.0.0.0.0.1.0.1", "3.0.0.0.0.1") ("3.0.0.1", "3.0") ("3.1.1", "3.1.1.1") 之类的
* @param {Object} v1
* @param {Object} v2
* v1 > v2 return 1
* v1 < v2 return -1
* v1 == v2 return 0
*/
function compare(v1 = '0', v2 = '0') {
v1 = String(v1).split('.')
v2 = String(v2).split('.')
const minVersionLens = Math.min(v1.length, v2.length);
let result = 0;
for (let i = 0; i < minVersionLens; i++) {
const curV1 = Number(v1[i])
const curV2 = Number(v2[i])
if (curV1 > curV2) {
result = 1
break;
} else if(curV1 < curV2) {
result = -1
break;
}
}
if (result === 0 && (v1.length !== v2.length)) {
const v1BiggerThenv2 = v1.length > v2.length;
const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
for (let i = minVersionLens; i < maxLensVersion.length; i++) {
const curVersion = Number(maxLensVersion[i])
if (curVersion > 0) {
v1BiggerThenv2 ? result = 1 : result = -1
break;
}
}
}
return result;
}

234
nx/utils/crypto-js/aes.js Normal file
View File

@@ -0,0 +1,234 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var BlockCipher = C_lib.BlockCipher;
var C_algo = C.algo;
// Lookup tables
var SBOX = [];
var INV_SBOX = [];
var SUB_MIX_0 = [];
var SUB_MIX_1 = [];
var SUB_MIX_2 = [];
var SUB_MIX_3 = [];
var INV_SUB_MIX_0 = [];
var INV_SUB_MIX_1 = [];
var INV_SUB_MIX_2 = [];
var INV_SUB_MIX_3 = [];
// Compute lookup tables
(function () {
// Compute double table
var d = [];
for (var i = 0; i < 256; i++) {
if (i < 128) {
d[i] = i << 1;
} else {
d[i] = (i << 1) ^ 0x11b;
}
}
// Walk GF(2^8)
var x = 0;
var xi = 0;
for (var i = 0; i < 256; i++) {
// Compute sbox
var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
SBOX[x] = sx;
INV_SBOX[sx] = x;
// Compute multiplication
var x2 = d[x];
var x4 = d[x2];
var x8 = d[x4];
// Compute sub bytes, mix columns tables
var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
SUB_MIX_0[x] = (t << 24) | (t >>> 8);
SUB_MIX_1[x] = (t << 16) | (t >>> 16);
SUB_MIX_2[x] = (t << 8) | (t >>> 24);
SUB_MIX_3[x] = t;
// Compute inv sub bytes, inv mix columns tables
var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24);
INV_SUB_MIX_3[sx] = t;
// Compute next counter
if (!x) {
x = xi = 1;
} else {
x = x2 ^ d[d[d[x8 ^ x2]]];
xi ^= d[d[xi]];
}
}
}());
// Precomputed Rcon lookup
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
/**
* AES block cipher algorithm.
*/
var AES = C_algo.AES = BlockCipher.extend({
_doReset: function () {
var t;
// Skip reset of nRounds has been set before and key did not change
if (this._nRounds && this._keyPriorReset === this._key) {
return;
}
// Shortcuts
var key = this._keyPriorReset = this._key;
var keyWords = key.words;
var keySize = key.sigBytes / 4;
// Compute number of rounds
var nRounds = this._nRounds = keySize + 6;
// Compute number of key schedule rows
var ksRows = (nRounds + 1) * 4;
// Compute key schedule
var keySchedule = this._keySchedule = [];
for (var ksRow = 0; ksRow < ksRows; ksRow++) {
if (ksRow < keySize) {
keySchedule[ksRow] = keyWords[ksRow];
} else {
t = keySchedule[ksRow - 1];
if (!(ksRow % keySize)) {
// Rot word
t = (t << 8) | (t >>> 24);
// Sub word
t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
// Mix Rcon
t ^= RCON[(ksRow / keySize) | 0] << 24;
} else if (keySize > 6 && ksRow % keySize == 4) {
// Sub word
t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
}
keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
}
}
// Compute inv key schedule
var invKeySchedule = this._invKeySchedule = [];
for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
var ksRow = ksRows - invKsRow;
if (invKsRow % 4) {
var t = keySchedule[ksRow];
} else {
var t = keySchedule[ksRow - 4];
}
if (invKsRow < 4 || ksRow <= 4) {
invKeySchedule[invKsRow] = t;
} else {
invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];
}
}
},
encryptBlock: function (M, offset) {
this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
},
decryptBlock: function (M, offset) {
// Swap 2nd and 4th rows
var t = M[offset + 1];
M[offset + 1] = M[offset + 3];
M[offset + 3] = t;
this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
// Inv swap 2nd and 4th rows
var t = M[offset + 1];
M[offset + 1] = M[offset + 3];
M[offset + 3] = t;
},
_doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
// Shortcut
var nRounds = this._nRounds;
// Get input, add round key
var s0 = M[offset] ^ keySchedule[0];
var s1 = M[offset + 1] ^ keySchedule[1];
var s2 = M[offset + 2] ^ keySchedule[2];
var s3 = M[offset + 3] ^ keySchedule[3];
// Key schedule row counter
var ksRow = 4;
// Rounds
for (var round = 1; round < nRounds; round++) {
// Shift rows, sub bytes, mix columns, add round key
var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];
var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];
var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];
var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];
// Update state
s0 = t0;
s1 = t1;
s2 = t2;
s3 = t3;
}
// Shift rows, sub bytes, add round key
var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
// Set output
M[offset] = t0;
M[offset + 1] = t1;
M[offset + 2] = t2;
M[offset + 3] = t3;
},
keySize: 256/32
});
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
* var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg);
*/
C.AES = BlockCipher._createHelper(AES);
}());
return CryptoJS.AES;
}));

View File

@@ -0,0 +1,39 @@
{
"name": "crypto-js",
"version": "4.1.1",
"description": "JavaScript library of crypto standards.",
"license": "MIT",
"homepage": "http://github.com/brix/crypto-js",
"repository": {
"type": "git",
"url": "http://github.com/brix/crypto-js.git"
},
"keywords": [
"security",
"crypto",
"Hash",
"MD5",
"SHA1",
"SHA-1",
"SHA256",
"SHA-256",
"RC4",
"Rabbit",
"AES",
"DES",
"PBKDF2",
"HMAC",
"OFB",
"CFB",
"CTR",
"CBC",
"Base64",
"Base64url"
],
"main": "index.js",
"dependencies": {},
"browser": {
"crypto": false
},
"ignore": []
}

View File

@@ -0,0 +1,890 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./evpkdf"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./evpkdf"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* Cipher core components.
*/
CryptoJS.lib.Cipher || (function (undefined) {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var Base = C_lib.Base;
var WordArray = C_lib.WordArray;
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
var C_enc = C.enc;
var Utf8 = C_enc.Utf8;
var Base64 = C_enc.Base64;
var C_algo = C.algo;
var EvpKDF = C_algo.EvpKDF;
/**
* Abstract base cipher template.
*
* @property {number} keySize This cipher's key size. Default: 4 (128 bits)
* @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
* @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
* @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
*/
var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({
/**
* Configuration options.
*
* @property {WordArray} iv The IV to use for this operation.
*/
cfg: Base.extend(),
/**
* Creates this cipher in encryption mode.
*
* @param {WordArray} key The key.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @return {Cipher} A cipher instance.
*
* @static
*
* @example
*
* var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
*/
createEncryptor: function (key, cfg) {
return this.create(this._ENC_XFORM_MODE, key, cfg);
},
/**
* Creates this cipher in decryption mode.
*
* @param {WordArray} key The key.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @return {Cipher} A cipher instance.
*
* @static
*
* @example
*
* var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
*/
createDecryptor: function (key, cfg) {
return this.create(this._DEC_XFORM_MODE, key, cfg);
},
/**
* Initializes a newly created cipher.
*
* @param {number} xformMode Either the encryption or decryption transormation mode constant.
* @param {WordArray} key The key.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @example
*
* var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
*/
init: function (xformMode, key, cfg) {
// Apply config defaults
this.cfg = this.cfg.extend(cfg);
// Store transform mode and key
this._xformMode = xformMode;
this._key = key;
// Set initial values
this.reset();
},
/**
* Resets this cipher to its initial state.
*
* @example
*
* cipher.reset();
*/
reset: function () {
// Reset data buffer
BufferedBlockAlgorithm.reset.call(this);
// Perform concrete-cipher logic
this._doReset();
},
/**
* Adds data to be encrypted or decrypted.
*
* @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
*
* @return {WordArray} The data after processing.
*
* @example
*
* var encrypted = cipher.process('data');
* var encrypted = cipher.process(wordArray);
*/
process: function (dataUpdate) {
// Append
this._append(dataUpdate);
// Process available blocks
return this._process();
},
/**
* Finalizes the encryption or decryption process.
* Note that the finalize operation is effectively a destructive, read-once operation.
*
* @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
*
* @return {WordArray} The data after final processing.
*
* @example
*
* var encrypted = cipher.finalize();
* var encrypted = cipher.finalize('data');
* var encrypted = cipher.finalize(wordArray);
*/
finalize: function (dataUpdate) {
// Final data update
if (dataUpdate) {
this._append(dataUpdate);
}
// Perform concrete-cipher logic
var finalProcessedData = this._doFinalize();
return finalProcessedData;
},
keySize: 128/32,
ivSize: 128/32,
_ENC_XFORM_MODE: 1,
_DEC_XFORM_MODE: 2,
/**
* Creates shortcut functions to a cipher's object interface.
*
* @param {Cipher} cipher The cipher to create a helper for.
*
* @return {Object} An object with encrypt and decrypt shortcut functions.
*
* @static
*
* @example
*
* var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
*/
_createHelper: (function () {
function selectCipherStrategy(key) {
if (typeof key == 'string') {
return PasswordBasedCipher;
} else {
return SerializableCipher;
}
}
return function (cipher) {
return {
encrypt: function (message, key, cfg) {
return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
},
decrypt: function (ciphertext, key, cfg) {
return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
}
};
};
}())
});
/**
* Abstract base stream cipher template.
*
* @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
*/
var StreamCipher = C_lib.StreamCipher = Cipher.extend({
_doFinalize: function () {
// Process partial blocks
var finalProcessedBlocks = this._process(!!'flush');
return finalProcessedBlocks;
},
blockSize: 1
});
/**
* Mode namespace.
*/
var C_mode = C.mode = {};
/**
* Abstract base block cipher mode template.
*/
var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({
/**
* Creates this mode for encryption.
*
* @param {Cipher} cipher A block cipher instance.
* @param {Array} iv The IV words.
*
* @static
*
* @example
*
* var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
*/
createEncryptor: function (cipher, iv) {
return this.Encryptor.create(cipher, iv);
},
/**
* Creates this mode for decryption.
*
* @param {Cipher} cipher A block cipher instance.
* @param {Array} iv The IV words.
*
* @static
*
* @example
*
* var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
*/
createDecryptor: function (cipher, iv) {
return this.Decryptor.create(cipher, iv);
},
/**
* Initializes a newly created mode.
*
* @param {Cipher} cipher A block cipher instance.
* @param {Array} iv The IV words.
*
* @example
*
* var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
*/
init: function (cipher, iv) {
this._cipher = cipher;
this._iv = iv;
}
});
/**
* Cipher Block Chaining mode.
*/
var CBC = C_mode.CBC = (function () {
/**
* Abstract base CBC mode.
*/
var CBC = BlockCipherMode.extend();
/**
* CBC encryptor.
*/
CBC.Encryptor = CBC.extend({
/**
* Processes the data block at offset.
*
* @param {Array} words The data words to operate on.
* @param {number} offset The offset where the block starts.
*
* @example
*
* mode.processBlock(data.words, offset);
*/
processBlock: function (words, offset) {
// Shortcuts
var cipher = this._cipher;
var blockSize = cipher.blockSize;
// XOR and encrypt
xorBlock.call(this, words, offset, blockSize);
cipher.encryptBlock(words, offset);
// Remember this block to use with next block
this._prevBlock = words.slice(offset, offset + blockSize);
}
});
/**
* CBC decryptor.
*/
CBC.Decryptor = CBC.extend({
/**
* Processes the data block at offset.
*
* @param {Array} words The data words to operate on.
* @param {number} offset The offset where the block starts.
*
* @example
*
* mode.processBlock(data.words, offset);
*/
processBlock: function (words, offset) {
// Shortcuts
var cipher = this._cipher;
var blockSize = cipher.blockSize;
// Remember this block to use with next block
var thisBlock = words.slice(offset, offset + blockSize);
// Decrypt and XOR
cipher.decryptBlock(words, offset);
xorBlock.call(this, words, offset, blockSize);
// This block becomes the previous block
this._prevBlock = thisBlock;
}
});
function xorBlock(words, offset, blockSize) {
var block;
// Shortcut
var iv = this._iv;
// Choose mixing block
if (iv) {
block = iv;
// Remove IV for subsequent blocks
this._iv = undefined;
} else {
block = this._prevBlock;
}
// XOR blocks
for (var i = 0; i < blockSize; i++) {
words[offset + i] ^= block[i];
}
}
return CBC;
}());
/**
* Padding namespace.
*/
var C_pad = C.pad = {};
/**
* PKCS #5/7 padding strategy.
*/
var Pkcs7 = C_pad.Pkcs7 = {
/**
* Pads data using the algorithm defined in PKCS #5/7.
*
* @param {WordArray} data The data to pad.
* @param {number} blockSize The multiple that the data should be padded to.
*
* @static
*
* @example
*
* CryptoJS.pad.Pkcs7.pad(wordArray, 4);
*/
pad: function (data, blockSize) {
// Shortcut
var blockSizeBytes = blockSize * 4;
// Count padding bytes
var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
// Create padding word
var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;
// Create padding
var paddingWords = [];
for (var i = 0; i < nPaddingBytes; i += 4) {
paddingWords.push(paddingWord);
}
var padding = WordArray.create(paddingWords, nPaddingBytes);
// Add padding
data.concat(padding);
},
/**
* Unpads data that had been padded using the algorithm defined in PKCS #5/7.
*
* @param {WordArray} data The data to unpad.
*
* @static
*
* @example
*
* CryptoJS.pad.Pkcs7.unpad(wordArray);
*/
unpad: function (data) {
// Get number of padding bytes from last byte
var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
// Remove padding
data.sigBytes -= nPaddingBytes;
}
};
/**
* Abstract base block cipher template.
*
* @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
*/
var BlockCipher = C_lib.BlockCipher = Cipher.extend({
/**
* Configuration options.
*
* @property {Mode} mode The block mode to use. Default: CBC
* @property {Padding} padding The padding strategy to use. Default: Pkcs7
*/
cfg: Cipher.cfg.extend({
mode: CBC,
padding: Pkcs7
}),
reset: function () {
var modeCreator;
// Reset cipher
Cipher.reset.call(this);
// Shortcuts
var cfg = this.cfg;
var iv = cfg.iv;
var mode = cfg.mode;
// Reset block mode
if (this._xformMode == this._ENC_XFORM_MODE) {
modeCreator = mode.createEncryptor;
} else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
modeCreator = mode.createDecryptor;
// Keep at least one block in the buffer for unpadding
this._minBufferSize = 1;
}
if (this._mode && this._mode.__creator == modeCreator) {
this._mode.init(this, iv && iv.words);
} else {
this._mode = modeCreator.call(mode, this, iv && iv.words);
this._mode.__creator = modeCreator;
}
},
_doProcessBlock: function (words, offset) {
this._mode.processBlock(words, offset);
},
_doFinalize: function () {
var finalProcessedBlocks;
// Shortcut
var padding = this.cfg.padding;
// Finalize
if (this._xformMode == this._ENC_XFORM_MODE) {
// Pad data
padding.pad(this._data, this.blockSize);
// Process final blocks
finalProcessedBlocks = this._process(!!'flush');
} else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
// Process final blocks
finalProcessedBlocks = this._process(!!'flush');
// Unpad data
padding.unpad(finalProcessedBlocks);
}
return finalProcessedBlocks;
},
blockSize: 128/32
});
/**
* A collection of cipher parameters.
*
* @property {WordArray} ciphertext The raw ciphertext.
* @property {WordArray} key The key to this ciphertext.
* @property {WordArray} iv The IV used in the ciphering operation.
* @property {WordArray} salt The salt used with a key derivation function.
* @property {Cipher} algorithm The cipher algorithm.
* @property {Mode} mode The block mode used in the ciphering operation.
* @property {Padding} padding The padding scheme used in the ciphering operation.
* @property {number} blockSize The block size of the cipher.
* @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.
*/
var CipherParams = C_lib.CipherParams = Base.extend({
/**
* Initializes a newly created cipher params object.
*
* @param {Object} cipherParams An object with any of the possible cipher parameters.
*
* @example
*
* var cipherParams = CryptoJS.lib.CipherParams.create({
* ciphertext: ciphertextWordArray,
* key: keyWordArray,
* iv: ivWordArray,
* salt: saltWordArray,
* algorithm: CryptoJS.algo.AES,
* mode: CryptoJS.mode.CBC,
* padding: CryptoJS.pad.PKCS7,
* blockSize: 4,
* formatter: CryptoJS.format.OpenSSL
* });
*/
init: function (cipherParams) {
this.mixIn(cipherParams);
},
/**
* Converts this cipher params object to a string.
*
* @param {Format} formatter (Optional) The formatting strategy to use.
*
* @return {string} The stringified cipher params.
*
* @throws Error If neither the formatter nor the default formatter is set.
*
* @example
*
* var string = cipherParams + '';
* var string = cipherParams.toString();
* var string = cipherParams.toString(CryptoJS.format.OpenSSL);
*/
toString: function (formatter) {
return (formatter || this.formatter).stringify(this);
}
});
/**
* Format namespace.
*/
var C_format = C.format = {};
/**
* OpenSSL formatting strategy.
*/
var OpenSSLFormatter = C_format.OpenSSL = {
/**
* Converts a cipher params object to an OpenSSL-compatible string.
*
* @param {CipherParams} cipherParams The cipher params object.
*
* @return {string} The OpenSSL-compatible string.
*
* @static
*
* @example
*
* var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
*/
stringify: function (cipherParams) {
var wordArray;
// Shortcuts
var ciphertext = cipherParams.ciphertext;
var salt = cipherParams.salt;
// Format
if (salt) {
wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
} else {
wordArray = ciphertext;
}
return wordArray.toString(Base64);
},
/**
* Converts an OpenSSL-compatible string to a cipher params object.
*
* @param {string} openSSLStr The OpenSSL-compatible string.
*
* @return {CipherParams} The cipher params object.
*
* @static
*
* @example
*
* var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
*/
parse: function (openSSLStr) {
var salt;
// Parse base64
var ciphertext = Base64.parse(openSSLStr);
// Shortcut
var ciphertextWords = ciphertext.words;
// Test for salt
if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
// Extract salt
salt = WordArray.create(ciphertextWords.slice(2, 4));
// Remove salt from ciphertext
ciphertextWords.splice(0, 4);
ciphertext.sigBytes -= 16;
}
return CipherParams.create({ ciphertext: ciphertext, salt: salt });
}
};
/**
* A cipher wrapper that returns ciphertext as a serializable cipher params object.
*/
var SerializableCipher = C_lib.SerializableCipher = Base.extend({
/**
* Configuration options.
*
* @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL
*/
cfg: Base.extend({
format: OpenSSLFormatter
}),
/**
* Encrypts a message.
*
* @param {Cipher} cipher The cipher algorithm to use.
* @param {WordArray|string} message The message to encrypt.
* @param {WordArray} key The key.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @return {CipherParams} A cipher params object.
*
* @static
*
* @example
*
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
*/
encrypt: function (cipher, message, key, cfg) {
// Apply config defaults
cfg = this.cfg.extend(cfg);
// Encrypt
var encryptor = cipher.createEncryptor(key, cfg);
var ciphertext = encryptor.finalize(message);
// Shortcut
var cipherCfg = encryptor.cfg;
// Create and return serializable cipher params
return CipherParams.create({
ciphertext: ciphertext,
key: key,
iv: cipherCfg.iv,
algorithm: cipher,
mode: cipherCfg.mode,
padding: cipherCfg.padding,
blockSize: cipher.blockSize,
formatter: cfg.format
});
},
/**
* Decrypts serialized ciphertext.
*
* @param {Cipher} cipher The cipher algorithm to use.
* @param {CipherParams|string} ciphertext The ciphertext to decrypt.
* @param {WordArray} key The key.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @return {WordArray} The plaintext.
*
* @static
*
* @example
*
* var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
* var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
*/
decrypt: function (cipher, ciphertext, key, cfg) {
// Apply config defaults
cfg = this.cfg.extend(cfg);
// Convert string to CipherParams
ciphertext = this._parse(ciphertext, cfg.format);
// Decrypt
var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);
return plaintext;
},
/**
* Converts serialized ciphertext to CipherParams,
* else assumed CipherParams already and returns ciphertext unchanged.
*
* @param {CipherParams|string} ciphertext The ciphertext.
* @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.
*
* @return {CipherParams} The unserialized ciphertext.
*
* @static
*
* @example
*
* var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
*/
_parse: function (ciphertext, format) {
if (typeof ciphertext == 'string') {
return format.parse(ciphertext, this);
} else {
return ciphertext;
}
}
});
/**
* Key derivation function namespace.
*/
var C_kdf = C.kdf = {};
/**
* OpenSSL key derivation function.
*/
var OpenSSLKdf = C_kdf.OpenSSL = {
/**
* Derives a key and IV from a password.
*
* @param {string} password The password to derive from.
* @param {number} keySize The size in words of the key to generate.
* @param {number} ivSize The size in words of the IV to generate.
* @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
*
* @return {CipherParams} A cipher params object with the key, IV, and salt.
*
* @static
*
* @example
*
* var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
* var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
*/
execute: function (password, keySize, ivSize, salt) {
// Generate random salt
if (!salt) {
salt = WordArray.random(64/8);
}
// Derive key and IV
var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
// Separate key and IV
var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
key.sigBytes = keySize * 4;
// Return params
return CipherParams.create({ key: key, iv: iv, salt: salt });
}
};
/**
* A serializable cipher wrapper that derives the key from a password,
* and returns ciphertext as a serializable cipher params object.
*/
var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({
/**
* Configuration options.
*
* @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL
*/
cfg: SerializableCipher.cfg.extend({
kdf: OpenSSLKdf
}),
/**
* Encrypts a message using a password.
*
* @param {Cipher} cipher The cipher algorithm to use.
* @param {WordArray|string} message The message to encrypt.
* @param {string} password The password.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @return {CipherParams} A cipher params object.
*
* @static
*
* @example
*
* var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
* var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
*/
encrypt: function (cipher, message, password, cfg) {
// Apply config defaults
cfg = this.cfg.extend(cfg);
// Derive key and other params
var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
// Add IV to config
cfg.iv = derivedParams.iv;
// Encrypt
var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
// Mix in derived params
ciphertext.mixIn(derivedParams);
return ciphertext;
},
/**
* Decrypts serialized ciphertext using a password.
*
* @param {Cipher} cipher The cipher algorithm to use.
* @param {CipherParams|string} ciphertext The ciphertext to decrypt.
* @param {string} password The password.
* @param {Object} cfg (Optional) The configuration options to use for this operation.
*
* @return {WordArray} The plaintext.
*
* @static
*
* @example
*
* var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
* var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
*/
decrypt: function (cipher, ciphertext, password, cfg) {
// Apply config defaults
cfg = this.cfg.extend(cfg);
// Convert string to CipherParams
ciphertext = this._parse(ciphertext, cfg.format);
// Derive key and other params
var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
// Add IV to config
cfg.iv = derivedParams.iv;
// Decrypt
var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);
return plaintext;
}
});
}());
}));

807
nx/utils/crypto-js/core.js Normal file
View File

@@ -0,0 +1,807 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory();
}
else if (typeof define === "function" && define.amd) {
// AMD
define([], factory);
}
else {
// Global (browser)
root.CryptoJS = factory();
}
}(this, function () {
/*globals window, global, require*/
/**
* CryptoJS core components.
*/
var CryptoJS = CryptoJS || (function (Math, undefined) {
var crypto;
// Native crypto from window (Browser)
if (typeof window !== 'undefined' && window.crypto) {
crypto = window.crypto;
}
// Native crypto in web worker (Browser)
if (typeof self !== 'undefined' && self.crypto) {
crypto = self.crypto;
}
// Native crypto from worker
if (typeof globalThis !== 'undefined' && globalThis.crypto) {
crypto = globalThis.crypto;
}
// Native (experimental IE 11) crypto from window (Browser)
if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
crypto = window.msCrypto;
}
// Native crypto from global (NodeJS)
if (!crypto && typeof global !== 'undefined' && global.crypto) {
crypto = global.crypto;
}
// Native crypto import via require (NodeJS)
if (!crypto && typeof require === 'function') {
try {
crypto = require('crypto');
} catch (err) {}
}
/*
* Cryptographically secure pseudorandom number generator
*
* As Math.random() is cryptographically not safe to use
*/
var cryptoSecureRandomInt = function () {
if (crypto) {
// Use getRandomValues method (Browser)
if (typeof crypto.getRandomValues === 'function') {
try {
return crypto.getRandomValues(new Uint32Array(1))[0];
} catch (err) {}
}
// Use randomBytes method (NodeJS)
if (typeof crypto.randomBytes === 'function') {
try {
return crypto.randomBytes(4).readInt32LE();
} catch (err) {}
}
}
throw new Error('Native crypto module could not be used to get secure random number.');
};
/*
* Local polyfill of Object.create
*/
var create = Object.create || (function () {
function F() {}
return function (obj) {
var subtype;
F.prototype = obj;
subtype = new F();
F.prototype = null;
return subtype;
};
}());
/**
* CryptoJS namespace.
*/
var C = {};
/**
* Library namespace.
*/
var C_lib = C.lib = {};
/**
* Base object for prototypal inheritance.
*/
var Base = C_lib.Base = (function () {
return {
/**
* Creates a new object that inherits from this object.
*
* @param {Object} overrides Properties to copy into the new object.
*
* @return {Object} The new object.
*
* @static
*
* @example
*
* var MyType = CryptoJS.lib.Base.extend({
* field: 'value',
*
* method: function () {
* }
* });
*/
extend: function (overrides) {
// Spawn
var subtype = create(this);
// Augment
if (overrides) {
subtype.mixIn(overrides);
}
// Create default initializer
if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
subtype.init = function () {
subtype.$super.init.apply(this, arguments);
};
}
// Initializer's prototype is the subtype object
subtype.init.prototype = subtype;
// Reference supertype
subtype.$super = this;
return subtype;
},
/**
* Extends this object and runs the init method.
* Arguments to create() will be passed to init().
*
* @return {Object} The new object.
*
* @static
*
* @example
*
* var instance = MyType.create();
*/
create: function () {
var instance = this.extend();
instance.init.apply(instance, arguments);
return instance;
},
/**
* Initializes a newly created object.
* Override this method to add some logic when your objects are created.
*
* @example
*
* var MyType = CryptoJS.lib.Base.extend({
* init: function () {
* // ...
* }
* });
*/
init: function () {
},
/**
* Copies properties into this object.
*
* @param {Object} properties The properties to mix in.
*
* @example
*
* MyType.mixIn({
* field: 'value'
* });
*/
mixIn: function (properties) {
for (var propertyName in properties) {
if (properties.hasOwnProperty(propertyName)) {
this[propertyName] = properties[propertyName];
}
}
// IE won't copy toString using the loop above
if (properties.hasOwnProperty('toString')) {
this.toString = properties.toString;
}
},
/**
* Creates a copy of this object.
*
* @return {Object} The clone.
*
* @example
*
* var clone = instance.clone();
*/
clone: function () {
return this.init.prototype.extend(this);
}
};
}());
/**
* An array of 32-bit words.
*
* @property {Array} words The array of 32-bit words.
* @property {number} sigBytes The number of significant bytes in this word array.
*/
var WordArray = C_lib.WordArray = Base.extend({
/**
* Initializes a newly created word array.
*
* @param {Array} words (Optional) An array of 32-bit words.
* @param {number} sigBytes (Optional) The number of significant bytes in the words.
*
* @example
*
* var wordArray = CryptoJS.lib.WordArray.create();
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
*/
init: function (words, sigBytes) {
words = this.words = words || [];
if (sigBytes != undefined) {
this.sigBytes = sigBytes;
} else {
this.sigBytes = words.length * 4;
}
},
/**
* Converts this word array to a string.
*
* @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
*
* @return {string} The stringified word array.
*
* @example
*
* var string = wordArray + '';
* var string = wordArray.toString();
* var string = wordArray.toString(CryptoJS.enc.Utf8);
*/
toString: function (encoder) {
return (encoder || Hex).stringify(this);
},
/**
* Concatenates a word array to this word array.
*
* @param {WordArray} wordArray The word array to append.
*
* @return {WordArray} This word array.
*
* @example
*
* wordArray1.concat(wordArray2);
*/
concat: function (wordArray) {
// Shortcuts
var thisWords = this.words;
var thatWords = wordArray.words;
var thisSigBytes = this.sigBytes;
var thatSigBytes = wordArray.sigBytes;
// Clamp excess bits
this.clamp();
// Concat
if (thisSigBytes % 4) {
// Copy one byte at a time
for (var i = 0; i < thatSigBytes; i++) {
var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
}
} else {
// Copy one word at a time
for (var j = 0; j < thatSigBytes; j += 4) {
thisWords[(thisSigBytes + j) >>> 2] = thatWords[j >>> 2];
}
}
this.sigBytes += thatSigBytes;
// Chainable
return this;
},
/**
* Removes insignificant bits.
*
* @example
*
* wordArray.clamp();
*/
clamp: function () {
// Shortcuts
var words = this.words;
var sigBytes = this.sigBytes;
// Clamp
words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
words.length = Math.ceil(sigBytes / 4);
},
/**
* Creates a copy of this word array.
*
* @return {WordArray} The clone.
*
* @example
*
* var clone = wordArray.clone();
*/
clone: function () {
var clone = Base.clone.call(this);
clone.words = this.words.slice(0);
return clone;
},
/**
* Creates a word array filled with random bytes.
*
* @param {number} nBytes The number of random bytes to generate.
*
* @return {WordArray} The random word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.lib.WordArray.random(16);
*/
random: function (nBytes) {
var words = [];
for (var i = 0; i < nBytes; i += 4) {
words.push(cryptoSecureRandomInt());
}
return new WordArray.init(words, nBytes);
}
});
/**
* Encoder namespace.
*/
var C_enc = C.enc = {};
/**
* Hex encoding strategy.
*/
var Hex = C_enc.Hex = {
/**
* Converts a word array to a hex string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The hex string.
*
* @static
*
* @example
*
* var hexString = CryptoJS.enc.Hex.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
// Convert
var hexChars = [];
for (var i = 0; i < sigBytes; i++) {
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
hexChars.push((bite >>> 4).toString(16));
hexChars.push((bite & 0x0f).toString(16));
}
return hexChars.join('');
},
/**
* Converts a hex string to a word array.
*
* @param {string} hexStr The hex string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Hex.parse(hexString);
*/
parse: function (hexStr) {
// Shortcut
var hexStrLength = hexStr.length;
// Convert
var words = [];
for (var i = 0; i < hexStrLength; i += 2) {
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
}
return new WordArray.init(words, hexStrLength / 2);
}
};
/**
* Latin1 encoding strategy.
*/
var Latin1 = C_enc.Latin1 = {
/**
* Converts a word array to a Latin1 string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The Latin1 string.
*
* @static
*
* @example
*
* var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
// Convert
var latin1Chars = [];
for (var i = 0; i < sigBytes; i++) {
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
latin1Chars.push(String.fromCharCode(bite));
}
return latin1Chars.join('');
},
/**
* Converts a Latin1 string to a word array.
*
* @param {string} latin1Str The Latin1 string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
*/
parse: function (latin1Str) {
// Shortcut
var latin1StrLength = latin1Str.length;
// Convert
var words = [];
for (var i = 0; i < latin1StrLength; i++) {
words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
}
return new WordArray.init(words, latin1StrLength);
}
};
/**
* UTF-8 encoding strategy.
*/
var Utf8 = C_enc.Utf8 = {
/**
* Converts a word array to a UTF-8 string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The UTF-8 string.
*
* @static
*
* @example
*
* var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
*/
stringify: function (wordArray) {
try {
return decodeURIComponent(escape(Latin1.stringify(wordArray)));
} catch (e) {
throw new Error('Malformed UTF-8 data');
}
},
/**
* Converts a UTF-8 string to a word array.
*
* @param {string} utf8Str The UTF-8 string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
*/
parse: function (utf8Str) {
return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
}
};
/**
* Abstract buffered block algorithm template.
*
* The property blockSize must be implemented in a concrete subtype.
*
* @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
*/
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
/**
* Resets this block algorithm's data buffer to its initial state.
*
* @example
*
* bufferedBlockAlgorithm.reset();
*/
reset: function () {
// Initial values
this._data = new WordArray.init();
this._nDataBytes = 0;
},
/**
* Adds new data to this block algorithm's buffer.
*
* @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
*
* @example
*
* bufferedBlockAlgorithm._append('data');
* bufferedBlockAlgorithm._append(wordArray);
*/
_append: function (data) {
// Convert string to WordArray, else assume WordArray already
if (typeof data == 'string') {
data = Utf8.parse(data);
}
// Append
this._data.concat(data);
this._nDataBytes += data.sigBytes;
},
/**
* Processes available data blocks.
*
* This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
*
* @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
*
* @return {WordArray} The processed data.
*
* @example
*
* var processedData = bufferedBlockAlgorithm._process();
* var processedData = bufferedBlockAlgorithm._process(!!'flush');
*/
_process: function (doFlush) {
var processedWords;
// Shortcuts
var data = this._data;
var dataWords = data.words;
var dataSigBytes = data.sigBytes;
var blockSize = this.blockSize;
var blockSizeBytes = blockSize * 4;
// Count blocks ready
var nBlocksReady = dataSigBytes / blockSizeBytes;
if (doFlush) {
// Round up to include partial blocks
nBlocksReady = Math.ceil(nBlocksReady);
} else {
// Round down to include only full blocks,
// less the number of blocks that must remain in the buffer
nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
}
// Count words ready
var nWordsReady = nBlocksReady * blockSize;
// Count bytes ready
var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
// Process blocks
if (nWordsReady) {
for (var offset = 0; offset < nWordsReady; offset += blockSize) {
// Perform concrete-algorithm logic
this._doProcessBlock(dataWords, offset);
}
// Remove processed words
processedWords = dataWords.splice(0, nWordsReady);
data.sigBytes -= nBytesReady;
}
// Return processed words
return new WordArray.init(processedWords, nBytesReady);
},
/**
* Creates a copy of this object.
*
* @return {Object} The clone.
*
* @example
*
* var clone = bufferedBlockAlgorithm.clone();
*/
clone: function () {
var clone = Base.clone.call(this);
clone._data = this._data.clone();
return clone;
},
_minBufferSize: 0
});
/**
* Abstract hasher template.
*
* @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
*/
var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
/**
* Configuration options.
*/
cfg: Base.extend(),
/**
* Initializes a newly created hasher.
*
* @param {Object} cfg (Optional) The configuration options to use for this hash computation.
*
* @example
*
* var hasher = CryptoJS.algo.SHA256.create();
*/
init: function (cfg) {
// Apply config defaults
this.cfg = this.cfg.extend(cfg);
// Set initial values
this.reset();
},
/**
* Resets this hasher to its initial state.
*
* @example
*
* hasher.reset();
*/
reset: function () {
// Reset data buffer
BufferedBlockAlgorithm.reset.call(this);
// Perform concrete-hasher logic
this._doReset();
},
/**
* Updates this hasher with a message.
*
* @param {WordArray|string} messageUpdate The message to append.
*
* @return {Hasher} This hasher.
*
* @example
*
* hasher.update('message');
* hasher.update(wordArray);
*/
update: function (messageUpdate) {
// Append
this._append(messageUpdate);
// Update the hash
this._process();
// Chainable
return this;
},
/**
* Finalizes the hash computation.
* Note that the finalize operation is effectively a destructive, read-once operation.
*
* @param {WordArray|string} messageUpdate (Optional) A final message update.
*
* @return {WordArray} The hash.
*
* @example
*
* var hash = hasher.finalize();
* var hash = hasher.finalize('message');
* var hash = hasher.finalize(wordArray);
*/
finalize: function (messageUpdate) {
// Final message update
if (messageUpdate) {
this._append(messageUpdate);
}
// Perform concrete-hasher logic
var hash = this._doFinalize();
return hash;
},
blockSize: 512/32,
/**
* Creates a shortcut function to a hasher's object interface.
*
* @param {Hasher} hasher The hasher to create a helper for.
*
* @return {Function} The shortcut function.
*
* @static
*
* @example
*
* var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
*/
_createHelper: function (hasher) {
return function (message, cfg) {
return new hasher.init(cfg).finalize(message);
};
},
/**
* Creates a shortcut function to the HMAC's object interface.
*
* @param {Hasher} hasher The hasher to use in this HMAC helper.
*
* @return {Function} The shortcut function.
*
* @static
*
* @example
*
* var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
*/
_createHmacHelper: function (hasher) {
return function (message, key) {
return new C_algo.HMAC.init(hasher, key).finalize(message);
};
}
});
/**
* Algorithm namespace.
*/
var C_algo = C.algo = {};
return C;
}(Math));
return CryptoJS;
}));

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,136 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var C_enc = C.enc;
/**
* Base64 encoding strategy.
*/
var Base64 = C_enc.Base64 = {
/**
* Converts a word array to a Base64 string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The Base64 string.
*
* @static
*
* @example
*
* var base64String = CryptoJS.enc.Base64.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
var map = this._map;
// Clamp excess bits
wordArray.clamp();
// Convert
var base64Chars = [];
for (var i = 0; i < sigBytes; i += 3) {
var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
}
}
// Add padding
var paddingChar = map.charAt(64);
if (paddingChar) {
while (base64Chars.length % 4) {
base64Chars.push(paddingChar);
}
}
return base64Chars.join('');
},
/**
* Converts a Base64 string to a word array.
*
* @param {string} base64Str The Base64 string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Base64.parse(base64String);
*/
parse: function (base64Str) {
// Shortcuts
var base64StrLength = base64Str.length;
var map = this._map;
var reverseMap = this._reverseMap;
if (!reverseMap) {
reverseMap = this._reverseMap = [];
for (var j = 0; j < map.length; j++) {
reverseMap[map.charCodeAt(j)] = j;
}
}
// Ignore padding
var paddingChar = map.charAt(64);
if (paddingChar) {
var paddingIndex = base64Str.indexOf(paddingChar);
if (paddingIndex !== -1) {
base64StrLength = paddingIndex;
}
}
// Convert
return parseLoop(base64Str, base64StrLength, reverseMap);
},
_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
};
function parseLoop(base64Str, base64StrLength, reverseMap) {
var words = [];
var nBytes = 0;
for (var i = 0; i < base64StrLength; i++) {
if (i % 4) {
var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
var bitsCombined = bits1 | bits2;
words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);
nBytes++;
}
}
return WordArray.create(words, nBytes);
}
}());
return CryptoJS.enc.Base64;
}));

View File

@@ -0,0 +1,140 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var C_enc = C.enc;
/**
* Base64url encoding strategy.
*/
var Base64url = C_enc.Base64url = {
/**
* Converts a word array to a Base64url string.
*
* @param {WordArray} wordArray The word array.
*
* @param {boolean} urlSafe Whether to use url safe
*
* @return {string} The Base64url string.
*
* @static
*
* @example
*
* var base64String = CryptoJS.enc.Base64url.stringify(wordArray);
*/
stringify: function (wordArray, urlSafe=true) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
var map = urlSafe ? this._safe_map : this._map;
// Clamp excess bits
wordArray.clamp();
// Convert
var base64Chars = [];
for (var i = 0; i < sigBytes; i += 3) {
var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
}
}
// Add padding
var paddingChar = map.charAt(64);
if (paddingChar) {
while (base64Chars.length % 4) {
base64Chars.push(paddingChar);
}
}
return base64Chars.join('');
},
/**
* Converts a Base64url string to a word array.
*
* @param {string} base64Str The Base64url string.
*
* @param {boolean} urlSafe Whether to use url safe
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Base64url.parse(base64String);
*/
parse: function (base64Str, urlSafe=true) {
// Shortcuts
var base64StrLength = base64Str.length;
var map = urlSafe ? this._safe_map : this._map;
var reverseMap = this._reverseMap;
if (!reverseMap) {
reverseMap = this._reverseMap = [];
for (var j = 0; j < map.length; j++) {
reverseMap[map.charCodeAt(j)] = j;
}
}
// Ignore padding
var paddingChar = map.charAt(64);
if (paddingChar) {
var paddingIndex = base64Str.indexOf(paddingChar);
if (paddingIndex !== -1) {
base64StrLength = paddingIndex;
}
}
// Convert
return parseLoop(base64Str, base64StrLength, reverseMap);
},
_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
_safe_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
};
function parseLoop(base64Str, base64StrLength, reverseMap) {
var words = [];
var nBytes = 0;
for (var i = 0; i < base64StrLength; i++) {
if (i % 4) {
var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
var bitsCombined = bits1 | bits2;
words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);
nBytes++;
}
}
return WordArray.create(words, nBytes);
}
}());
return CryptoJS.enc.Base64url;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.enc.Hex;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.enc.Latin1;
}));

View File

@@ -0,0 +1,149 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var C_enc = C.enc;
/**
* UTF-16 BE encoding strategy.
*/
var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = {
/**
* Converts a word array to a UTF-16 BE string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The UTF-16 BE string.
*
* @static
*
* @example
*
* var utf16String = CryptoJS.enc.Utf16.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
// Convert
var utf16Chars = [];
for (var i = 0; i < sigBytes; i += 2) {
var codePoint = (words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff;
utf16Chars.push(String.fromCharCode(codePoint));
}
return utf16Chars.join('');
},
/**
* Converts a UTF-16 BE string to a word array.
*
* @param {string} utf16Str The UTF-16 BE string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Utf16.parse(utf16String);
*/
parse: function (utf16Str) {
// Shortcut
var utf16StrLength = utf16Str.length;
// Convert
var words = [];
for (var i = 0; i < utf16StrLength; i++) {
words[i >>> 1] |= utf16Str.charCodeAt(i) << (16 - (i % 2) * 16);
}
return WordArray.create(words, utf16StrLength * 2);
}
};
/**
* UTF-16 LE encoding strategy.
*/
C_enc.Utf16LE = {
/**
* Converts a word array to a UTF-16 LE string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The UTF-16 LE string.
*
* @static
*
* @example
*
* var utf16Str = CryptoJS.enc.Utf16LE.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
// Convert
var utf16Chars = [];
for (var i = 0; i < sigBytes; i += 2) {
var codePoint = swapEndian((words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff);
utf16Chars.push(String.fromCharCode(codePoint));
}
return utf16Chars.join('');
},
/**
* Converts a UTF-16 LE string to a word array.
*
* @param {string} utf16Str The UTF-16 LE string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Utf16LE.parse(utf16Str);
*/
parse: function (utf16Str) {
// Shortcut
var utf16StrLength = utf16Str.length;
// Convert
var words = [];
for (var i = 0; i < utf16StrLength; i++) {
words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << (16 - (i % 2) * 16));
}
return WordArray.create(words, utf16StrLength * 2);
}
};
function swapEndian(word) {
return ((word << 8) & 0xff00ff00) | ((word >>> 8) & 0x00ff00ff);
}
}());
return CryptoJS.enc.Utf16;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.enc.Utf8;
}));

View File

@@ -0,0 +1,134 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./sha1"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./sha1", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var Base = C_lib.Base;
var WordArray = C_lib.WordArray;
var C_algo = C.algo;
var MD5 = C_algo.MD5;
/**
* This key derivation function is meant to conform with EVP_BytesToKey.
* www.openssl.org/docs/crypto/EVP_BytesToKey.html
*/
var EvpKDF = C_algo.EvpKDF = Base.extend({
/**
* Configuration options.
*
* @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
* @property {Hasher} hasher The hash algorithm to use. Default: MD5
* @property {number} iterations The number of iterations to perform. Default: 1
*/
cfg: Base.extend({
keySize: 128/32,
hasher: MD5,
iterations: 1
}),
/**
* Initializes a newly created key derivation function.
*
* @param {Object} cfg (Optional) The configuration options to use for the derivation.
*
* @example
*
* var kdf = CryptoJS.algo.EvpKDF.create();
* var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });
* var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });
*/
init: function (cfg) {
this.cfg = this.cfg.extend(cfg);
},
/**
* Derives a key from a password.
*
* @param {WordArray|string} password The password.
* @param {WordArray|string} salt A salt.
*
* @return {WordArray} The derived key.
*
* @example
*
* var key = kdf.compute(password, salt);
*/
compute: function (password, salt) {
var block;
// Shortcut
var cfg = this.cfg;
// Init hasher
var hasher = cfg.hasher.create();
// Initial values
var derivedKey = WordArray.create();
// Shortcuts
var derivedKeyWords = derivedKey.words;
var keySize = cfg.keySize;
var iterations = cfg.iterations;
// Generate key
while (derivedKeyWords.length < keySize) {
if (block) {
hasher.update(block);
}
block = hasher.update(password).finalize(salt);
hasher.reset();
// Iterations
for (var i = 1; i < iterations; i++) {
block = hasher.finalize(block);
hasher.reset();
}
derivedKey.concat(block);
}
derivedKey.sigBytes = keySize * 4;
return derivedKey;
}
});
/**
* Derives a key from a password.
*
* @param {WordArray|string} password The password.
* @param {WordArray|string} salt A salt.
* @param {Object} cfg (Optional) The configuration options to use for this computation.
*
* @return {WordArray} The derived key.
*
* @static
*
* @example
*
* var key = CryptoJS.EvpKDF(password, salt);
* var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
* var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
*/
C.EvpKDF = function (password, salt, cfg) {
return EvpKDF.create(cfg).compute(password, salt);
};
}());
return CryptoJS.EvpKDF;
}));

View File

@@ -0,0 +1,66 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function (undefined) {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var CipherParams = C_lib.CipherParams;
var C_enc = C.enc;
var Hex = C_enc.Hex;
var C_format = C.format;
var HexFormatter = C_format.Hex = {
/**
* Converts the ciphertext of a cipher params object to a hexadecimally encoded string.
*
* @param {CipherParams} cipherParams The cipher params object.
*
* @return {string} The hexadecimally encoded string.
*
* @static
*
* @example
*
* var hexString = CryptoJS.format.Hex.stringify(cipherParams);
*/
stringify: function (cipherParams) {
return cipherParams.ciphertext.toString(Hex);
},
/**
* Converts a hexadecimally encoded ciphertext string to a cipher params object.
*
* @param {string} input The hexadecimally encoded string.
*
* @return {CipherParams} The cipher params object.
*
* @static
*
* @example
*
* var cipherParams = CryptoJS.format.Hex.parse(hexString);
*/
parse: function (input) {
var ciphertext = Hex.parse(input);
return CipherParams.create({ ciphertext: ciphertext });
}
};
}());
return CryptoJS.format.Hex;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.format.OpenSSL;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./md5"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./md5", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.HmacMD5;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./ripemd160"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./ripemd160", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.HmacRIPEMD160;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./sha1"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./sha1", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.HmacSHA1;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./sha256"), require("./sha224"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./sha256", "./sha224", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.HmacSHA224;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./sha256"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./sha256", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.HmacSHA256;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./x64-core"), require("./sha3"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./x64-core", "./sha3", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.HmacSHA3;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./x64-core"), require("./sha512"), require("./sha384"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./x64-core", "./sha512", "./sha384", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.HmacSHA384;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./x64-core"), require("./sha512"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./x64-core", "./sha512", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.HmacSHA512;
}));

143
nx/utils/crypto-js/hmac.js Normal file
View File

@@ -0,0 +1,143 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var Base = C_lib.Base;
var C_enc = C.enc;
var Utf8 = C_enc.Utf8;
var C_algo = C.algo;
/**
* HMAC algorithm.
*/
var HMAC = C_algo.HMAC = Base.extend({
/**
* Initializes a newly created HMAC.
*
* @param {Hasher} hasher The hash algorithm to use.
* @param {WordArray|string} key The secret key.
*
* @example
*
* var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
*/
init: function (hasher, key) {
// Init hasher
hasher = this._hasher = new hasher.init();
// Convert string to WordArray, else assume WordArray already
if (typeof key == 'string') {
key = Utf8.parse(key);
}
// Shortcuts
var hasherBlockSize = hasher.blockSize;
var hasherBlockSizeBytes = hasherBlockSize * 4;
// Allow arbitrary length keys
if (key.sigBytes > hasherBlockSizeBytes) {
key = hasher.finalize(key);
}
// Clamp excess bits
key.clamp();
// Clone key for inner and outer pads
var oKey = this._oKey = key.clone();
var iKey = this._iKey = key.clone();
// Shortcuts
var oKeyWords = oKey.words;
var iKeyWords = iKey.words;
// XOR keys with pad constants
for (var i = 0; i < hasherBlockSize; i++) {
oKeyWords[i] ^= 0x5c5c5c5c;
iKeyWords[i] ^= 0x36363636;
}
oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes;
// Set initial values
this.reset();
},
/**
* Resets this HMAC to its initial state.
*
* @example
*
* hmacHasher.reset();
*/
reset: function () {
// Shortcut
var hasher = this._hasher;
// Reset
hasher.reset();
hasher.update(this._iKey);
},
/**
* Updates this HMAC with a message.
*
* @param {WordArray|string} messageUpdate The message to append.
*
* @return {HMAC} This HMAC instance.
*
* @example
*
* hmacHasher.update('message');
* hmacHasher.update(wordArray);
*/
update: function (messageUpdate) {
this._hasher.update(messageUpdate);
// Chainable
return this;
},
/**
* Finalizes the HMAC computation.
* Note that the finalize operation is effectively a destructive, read-once operation.
*
* @param {WordArray|string} messageUpdate (Optional) A final message update.
*
* @return {WordArray} The HMAC.
*
* @example
*
* var hmac = hmacHasher.finalize();
* var hmac = hmacHasher.finalize('message');
* var hmac = hmacHasher.finalize(wordArray);
*/
finalize: function (messageUpdate) {
// Shortcut
var hasher = this._hasher;
// Compute HMAC
var innerHash = hasher.finalize(messageUpdate);
hasher.reset();
var hmac = hasher.finalize(this._oKey.clone().concat(innerHash));
return hmac;
}
});
}());
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./x64-core"), require("./lib-typedarrays"), require("./enc-utf16"), require("./enc-base64"), require("./enc-base64url"), require("./md5"), require("./sha1"), require("./sha256"), require("./sha224"), require("./sha512"), require("./sha384"), require("./sha3"), require("./ripemd160"), require("./hmac"), require("./pbkdf2"), require("./evpkdf"), require("./cipher-core"), require("./mode-cfb"), require("./mode-ctr"), require("./mode-ctr-gladman"), require("./mode-ofb"), require("./mode-ecb"), require("./pad-ansix923"), require("./pad-iso10126"), require("./pad-iso97971"), require("./pad-zeropadding"), require("./pad-nopadding"), require("./format-hex"), require("./aes"), require("./tripledes"), require("./rc4"), require("./rabbit"), require("./rabbit-legacy"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./x64-core", "./lib-typedarrays", "./enc-utf16", "./enc-base64", "./enc-base64url", "./md5", "./sha1", "./sha256", "./sha224", "./sha512", "./sha384", "./sha3", "./ripemd160", "./hmac", "./pbkdf2", "./evpkdf", "./cipher-core", "./mode-cfb", "./mode-ctr", "./mode-ctr-gladman", "./mode-ofb", "./mode-ecb", "./pad-ansix923", "./pad-iso10126", "./pad-iso97971", "./pad-zeropadding", "./pad-nopadding", "./format-hex", "./aes", "./tripledes", "./rc4", "./rabbit", "./rabbit-legacy"], factory);
}
else {
// Global (browser)
root.CryptoJS = factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS;
}));

View File

@@ -0,0 +1,76 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Check if typed arrays are supported
if (typeof ArrayBuffer != 'function') {
return;
}
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
// Reference original init
var superInit = WordArray.init;
// Augment WordArray.init to handle typed arrays
var subInit = WordArray.init = function (typedArray) {
// Convert buffers to uint8
if (typedArray instanceof ArrayBuffer) {
typedArray = new Uint8Array(typedArray);
}
// Convert other array views to uint8
if (
typedArray instanceof Int8Array ||
(typeof Uint8ClampedArray !== "undefined" && typedArray instanceof Uint8ClampedArray) ||
typedArray instanceof Int16Array ||
typedArray instanceof Uint16Array ||
typedArray instanceof Int32Array ||
typedArray instanceof Uint32Array ||
typedArray instanceof Float32Array ||
typedArray instanceof Float64Array
) {
typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength);
}
// Handle Uint8Array
if (typedArray instanceof Uint8Array) {
// Shortcut
var typedArrayByteLength = typedArray.byteLength;
// Extract bytes
var words = [];
for (var i = 0; i < typedArrayByteLength; i++) {
words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8);
}
// Initialize this word array
superInit.call(this, words, typedArrayByteLength);
} else {
// Else call normal init
superInit.apply(this, arguments);
}
};
subInit.prototype = WordArray;
}());
return CryptoJS.lib.WordArray;
}));

268
nx/utils/crypto-js/md5.js Normal file
View File

@@ -0,0 +1,268 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function (Math) {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var Hasher = C_lib.Hasher;
var C_algo = C.algo;
// Constants table
var T = [];
// Compute constants
(function () {
for (var i = 0; i < 64; i++) {
T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
}
}());
/**
* MD5 hash algorithm.
*/
var MD5 = C_algo.MD5 = Hasher.extend({
_doReset: function () {
this._hash = new WordArray.init([
0x67452301, 0xefcdab89,
0x98badcfe, 0x10325476
]);
},
_doProcessBlock: function (M, offset) {
// Swap endian
for (var i = 0; i < 16; i++) {
// Shortcuts
var offset_i = offset + i;
var M_offset_i = M[offset_i];
M[offset_i] = (
(((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
(((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
);
}
// Shortcuts
var H = this._hash.words;
var M_offset_0 = M[offset + 0];
var M_offset_1 = M[offset + 1];
var M_offset_2 = M[offset + 2];
var M_offset_3 = M[offset + 3];
var M_offset_4 = M[offset + 4];
var M_offset_5 = M[offset + 5];
var M_offset_6 = M[offset + 6];
var M_offset_7 = M[offset + 7];
var M_offset_8 = M[offset + 8];
var M_offset_9 = M[offset + 9];
var M_offset_10 = M[offset + 10];
var M_offset_11 = M[offset + 11];
var M_offset_12 = M[offset + 12];
var M_offset_13 = M[offset + 13];
var M_offset_14 = M[offset + 14];
var M_offset_15 = M[offset + 15];
// Working varialbes
var a = H[0];
var b = H[1];
var c = H[2];
var d = H[3];
// Computation
a = FF(a, b, c, d, M_offset_0, 7, T[0]);
d = FF(d, a, b, c, M_offset_1, 12, T[1]);
c = FF(c, d, a, b, M_offset_2, 17, T[2]);
b = FF(b, c, d, a, M_offset_3, 22, T[3]);
a = FF(a, b, c, d, M_offset_4, 7, T[4]);
d = FF(d, a, b, c, M_offset_5, 12, T[5]);
c = FF(c, d, a, b, M_offset_6, 17, T[6]);
b = FF(b, c, d, a, M_offset_7, 22, T[7]);
a = FF(a, b, c, d, M_offset_8, 7, T[8]);
d = FF(d, a, b, c, M_offset_9, 12, T[9]);
c = FF(c, d, a, b, M_offset_10, 17, T[10]);
b = FF(b, c, d, a, M_offset_11, 22, T[11]);
a = FF(a, b, c, d, M_offset_12, 7, T[12]);
d = FF(d, a, b, c, M_offset_13, 12, T[13]);
c = FF(c, d, a, b, M_offset_14, 17, T[14]);
b = FF(b, c, d, a, M_offset_15, 22, T[15]);
a = GG(a, b, c, d, M_offset_1, 5, T[16]);
d = GG(d, a, b, c, M_offset_6, 9, T[17]);
c = GG(c, d, a, b, M_offset_11, 14, T[18]);
b = GG(b, c, d, a, M_offset_0, 20, T[19]);
a = GG(a, b, c, d, M_offset_5, 5, T[20]);
d = GG(d, a, b, c, M_offset_10, 9, T[21]);
c = GG(c, d, a, b, M_offset_15, 14, T[22]);
b = GG(b, c, d, a, M_offset_4, 20, T[23]);
a = GG(a, b, c, d, M_offset_9, 5, T[24]);
d = GG(d, a, b, c, M_offset_14, 9, T[25]);
c = GG(c, d, a, b, M_offset_3, 14, T[26]);
b = GG(b, c, d, a, M_offset_8, 20, T[27]);
a = GG(a, b, c, d, M_offset_13, 5, T[28]);
d = GG(d, a, b, c, M_offset_2, 9, T[29]);
c = GG(c, d, a, b, M_offset_7, 14, T[30]);
b = GG(b, c, d, a, M_offset_12, 20, T[31]);
a = HH(a, b, c, d, M_offset_5, 4, T[32]);
d = HH(d, a, b, c, M_offset_8, 11, T[33]);
c = HH(c, d, a, b, M_offset_11, 16, T[34]);
b = HH(b, c, d, a, M_offset_14, 23, T[35]);
a = HH(a, b, c, d, M_offset_1, 4, T[36]);
d = HH(d, a, b, c, M_offset_4, 11, T[37]);
c = HH(c, d, a, b, M_offset_7, 16, T[38]);
b = HH(b, c, d, a, M_offset_10, 23, T[39]);
a = HH(a, b, c, d, M_offset_13, 4, T[40]);
d = HH(d, a, b, c, M_offset_0, 11, T[41]);
c = HH(c, d, a, b, M_offset_3, 16, T[42]);
b = HH(b, c, d, a, M_offset_6, 23, T[43]);
a = HH(a, b, c, d, M_offset_9, 4, T[44]);
d = HH(d, a, b, c, M_offset_12, 11, T[45]);
c = HH(c, d, a, b, M_offset_15, 16, T[46]);
b = HH(b, c, d, a, M_offset_2, 23, T[47]);
a = II(a, b, c, d, M_offset_0, 6, T[48]);
d = II(d, a, b, c, M_offset_7, 10, T[49]);
c = II(c, d, a, b, M_offset_14, 15, T[50]);
b = II(b, c, d, a, M_offset_5, 21, T[51]);
a = II(a, b, c, d, M_offset_12, 6, T[52]);
d = II(d, a, b, c, M_offset_3, 10, T[53]);
c = II(c, d, a, b, M_offset_10, 15, T[54]);
b = II(b, c, d, a, M_offset_1, 21, T[55]);
a = II(a, b, c, d, M_offset_8, 6, T[56]);
d = II(d, a, b, c, M_offset_15, 10, T[57]);
c = II(c, d, a, b, M_offset_6, 15, T[58]);
b = II(b, c, d, a, M_offset_13, 21, T[59]);
a = II(a, b, c, d, M_offset_4, 6, T[60]);
d = II(d, a, b, c, M_offset_11, 10, T[61]);
c = II(c, d, a, b, M_offset_2, 15, T[62]);
b = II(b, c, d, a, M_offset_9, 21, T[63]);
// Intermediate hash value
H[0] = (H[0] + a) | 0;
H[1] = (H[1] + b) | 0;
H[2] = (H[2] + c) | 0;
H[3] = (H[3] + d) | 0;
},
_doFinalize: function () {
// Shortcuts
var data = this._data;
var dataWords = data.words;
var nBitsTotal = this._nDataBytes * 8;
var nBitsLeft = data.sigBytes * 8;
// Add padding
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
var nBitsTotalL = nBitsTotal;
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (
(((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
(((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00)
);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
(((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
(((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00)
);
data.sigBytes = (dataWords.length + 1) * 4;
// Hash final blocks
this._process();
// Shortcuts
var hash = this._hash;
var H = hash.words;
// Swap endian
for (var i = 0; i < 4; i++) {
// Shortcut
var H_i = H[i];
H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
(((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
}
// Return final computed hash
return hash;
},
clone: function () {
var clone = Hasher.clone.call(this);
clone._hash = this._hash.clone();
return clone;
}
});
function FF(a, b, c, d, x, s, t) {
var n = a + ((b & c) | (~b & d)) + x + t;
return ((n << s) | (n >>> (32 - s))) + b;
}
function GG(a, b, c, d, x, s, t) {
var n = a + ((b & d) | (c & ~d)) + x + t;
return ((n << s) | (n >>> (32 - s))) + b;
}
function HH(a, b, c, d, x, s, t) {
var n = a + (b ^ c ^ d) + x + t;
return ((n << s) | (n >>> (32 - s))) + b;
}
function II(a, b, c, d, x, s, t) {
var n = a + (c ^ (b | ~d)) + x + t;
return ((n << s) | (n >>> (32 - s))) + b;
}
/**
* Shortcut function to the hasher's object interface.
*
* @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.MD5('message');
* var hash = CryptoJS.MD5(wordArray);
*/
C.MD5 = Hasher._createHelper(MD5);
/**
* Shortcut function to the HMAC's object interface.
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacMD5(message, key);
*/
C.HmacMD5 = Hasher._createHmacHelper(MD5);
}(Math));
return CryptoJS.MD5;
}));

View File

@@ -0,0 +1,80 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* Cipher Feedback block mode.
*/
CryptoJS.mode.CFB = (function () {
var CFB = CryptoJS.lib.BlockCipherMode.extend();
CFB.Encryptor = CFB.extend({
processBlock: function (words, offset) {
// Shortcuts
var cipher = this._cipher;
var blockSize = cipher.blockSize;
generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
// Remember this block to use with next block
this._prevBlock = words.slice(offset, offset + blockSize);
}
});
CFB.Decryptor = CFB.extend({
processBlock: function (words, offset) {
// Shortcuts
var cipher = this._cipher;
var blockSize = cipher.blockSize;
// Remember this block to use with next block
var thisBlock = words.slice(offset, offset + blockSize);
generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
// This block becomes the previous block
this._prevBlock = thisBlock;
}
});
function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) {
var keystream;
// Shortcut
var iv = this._iv;
// Generate keystream
if (iv) {
keystream = iv.slice(0);
// Remove IV for subsequent blocks
this._iv = undefined;
} else {
keystream = this._prevBlock;
}
cipher.encryptBlock(keystream, 0);
// Encrypt
for (var i = 0; i < blockSize; i++) {
words[offset + i] ^= keystream[i];
}
}
return CFB;
}());
return CryptoJS.mode.CFB;
}));

View File

@@ -0,0 +1,116 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/** @preserve
* Counter block mode compatible with Dr Brian Gladman fileenc.c
* derived from CryptoJS.mode.CTR
* Jan Hruby jhruby.web@gmail.com
*/
CryptoJS.mode.CTRGladman = (function () {
var CTRGladman = CryptoJS.lib.BlockCipherMode.extend();
function incWord(word)
{
if (((word >> 24) & 0xff) === 0xff) { //overflow
var b1 = (word >> 16)&0xff;
var b2 = (word >> 8)&0xff;
var b3 = word & 0xff;
if (b1 === 0xff) // overflow b1
{
b1 = 0;
if (b2 === 0xff)
{
b2 = 0;
if (b3 === 0xff)
{
b3 = 0;
}
else
{
++b3;
}
}
else
{
++b2;
}
}
else
{
++b1;
}
word = 0;
word += (b1 << 16);
word += (b2 << 8);
word += b3;
}
else
{
word += (0x01 << 24);
}
return word;
}
function incCounter(counter)
{
if ((counter[0] = incWord(counter[0])) === 0)
{
// encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8
counter[1] = incWord(counter[1]);
}
return counter;
}
var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({
processBlock: function (words, offset) {
// Shortcuts
var cipher = this._cipher
var blockSize = cipher.blockSize;
var iv = this._iv;
var counter = this._counter;
// Generate keystream
if (iv) {
counter = this._counter = iv.slice(0);
// Remove IV for subsequent blocks
this._iv = undefined;
}
incCounter(counter);
var keystream = counter.slice(0);
cipher.encryptBlock(keystream, 0);
// Encrypt
for (var i = 0; i < blockSize; i++) {
words[offset + i] ^= keystream[i];
}
}
});
CTRGladman.Decryptor = Encryptor;
return CTRGladman;
}());
return CryptoJS.mode.CTRGladman;
}));

View File

@@ -0,0 +1,58 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* Counter block mode.
*/
CryptoJS.mode.CTR = (function () {
var CTR = CryptoJS.lib.BlockCipherMode.extend();
var Encryptor = CTR.Encryptor = CTR.extend({
processBlock: function (words, offset) {
// Shortcuts
var cipher = this._cipher
var blockSize = cipher.blockSize;
var iv = this._iv;
var counter = this._counter;
// Generate keystream
if (iv) {
counter = this._counter = iv.slice(0);
// Remove IV for subsequent blocks
this._iv = undefined;
}
var keystream = counter.slice(0);
cipher.encryptBlock(keystream, 0);
// Increment counter
counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0
// Encrypt
for (var i = 0; i < blockSize; i++) {
words[offset + i] ^= keystream[i];
}
}
});
CTR.Decryptor = Encryptor;
return CTR;
}());
return CryptoJS.mode.CTR;
}));

View File

@@ -0,0 +1,40 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* Electronic Codebook block mode.
*/
CryptoJS.mode.ECB = (function () {
var ECB = CryptoJS.lib.BlockCipherMode.extend();
ECB.Encryptor = ECB.extend({
processBlock: function (words, offset) {
this._cipher.encryptBlock(words, offset);
}
});
ECB.Decryptor = ECB.extend({
processBlock: function (words, offset) {
this._cipher.decryptBlock(words, offset);
}
});
return ECB;
}());
return CryptoJS.mode.ECB;
}));

View File

@@ -0,0 +1,54 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* Output Feedback block mode.
*/
CryptoJS.mode.OFB = (function () {
var OFB = CryptoJS.lib.BlockCipherMode.extend();
var Encryptor = OFB.Encryptor = OFB.extend({
processBlock: function (words, offset) {
// Shortcuts
var cipher = this._cipher
var blockSize = cipher.blockSize;
var iv = this._iv;
var keystream = this._keystream;
// Generate keystream
if (iv) {
keystream = this._keystream = iv.slice(0);
// Remove IV for subsequent blocks
this._iv = undefined;
}
cipher.encryptBlock(keystream, 0);
// Encrypt
for (var i = 0; i < blockSize; i++) {
words[offset + i] ^= keystream[i];
}
}
});
OFB.Decryptor = Encryptor;
return OFB;
}());
return CryptoJS.mode.OFB;
}));

View File

@@ -0,0 +1,42 @@
{
"name": "crypto-js",
"version": "4.1.1",
"description": "JavaScript library of crypto standards.",
"license": "MIT",
"author": {
"name": "Evan Vosberg",
"url": "http://github.com/evanvosberg"
},
"homepage": "http://github.com/brix/crypto-js",
"repository": {
"type": "git",
"url": "http://github.com/brix/crypto-js.git"
},
"keywords": [
"security",
"crypto",
"Hash",
"MD5",
"SHA1",
"SHA-1",
"SHA256",
"SHA-256",
"RC4",
"Rabbit",
"AES",
"DES",
"PBKDF2",
"HMAC",
"OFB",
"CFB",
"CTR",
"CBC",
"Base64",
"Base64url"
],
"main": "index.js",
"dependencies": {},
"browser": {
"crypto": false
}
}

View File

@@ -0,0 +1,49 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* ANSI X.923 padding strategy.
*/
CryptoJS.pad.AnsiX923 = {
pad: function (data, blockSize) {
// Shortcuts
var dataSigBytes = data.sigBytes;
var blockSizeBytes = blockSize * 4;
// Count padding bytes
var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes;
// Compute last byte position
var lastBytePos = dataSigBytes + nPaddingBytes - 1;
// Pad
data.clamp();
data.words[lastBytePos >>> 2] |= nPaddingBytes << (24 - (lastBytePos % 4) * 8);
data.sigBytes += nPaddingBytes;
},
unpad: function (data) {
// Get number of padding bytes from last byte
var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
// Remove padding
data.sigBytes -= nPaddingBytes;
}
};
return CryptoJS.pad.Ansix923;
}));

View File

@@ -0,0 +1,44 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* ISO 10126 padding strategy.
*/
CryptoJS.pad.Iso10126 = {
pad: function (data, blockSize) {
// Shortcut
var blockSizeBytes = blockSize * 4;
// Count padding bytes
var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
// Pad
data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)).
concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1));
},
unpad: function (data) {
// Get number of padding bytes from last byte
var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
// Remove padding
data.sigBytes -= nPaddingBytes;
}
};
return CryptoJS.pad.Iso10126;
}));

View File

@@ -0,0 +1,40 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* ISO/IEC 9797-1 Padding Method 2.
*/
CryptoJS.pad.Iso97971 = {
pad: function (data, blockSize) {
// Add 0x80 byte
data.concat(CryptoJS.lib.WordArray.create([0x80000000], 1));
// Zero pad the rest
CryptoJS.pad.ZeroPadding.pad(data, blockSize);
},
unpad: function (data) {
// Remove zero padding
CryptoJS.pad.ZeroPadding.unpad(data);
// Remove one more byte -- the 0x80 byte
data.sigBytes--;
}
};
return CryptoJS.pad.Iso97971;
}));

View File

@@ -0,0 +1,30 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* A noop padding strategy.
*/
CryptoJS.pad.NoPadding = {
pad: function () {
},
unpad: function () {
}
};
return CryptoJS.pad.NoPadding;
}));

View File

@@ -0,0 +1,18 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
return CryptoJS.pad.Pkcs7;
}));

View File

@@ -0,0 +1,47 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/**
* Zero padding strategy.
*/
CryptoJS.pad.ZeroPadding = {
pad: function (data, blockSize) {
// Shortcut
var blockSizeBytes = blockSize * 4;
// Pad
data.clamp();
data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);
},
unpad: function (data) {
// Shortcut
var dataWords = data.words;
// Unpad
var i = data.sigBytes - 1;
for (var i = data.sigBytes - 1; i >= 0; i--) {
if (((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) {
data.sigBytes = i + 1;
break;
}
}
}
};
return CryptoJS.pad.ZeroPadding;
}));

View File

@@ -0,0 +1,145 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./sha1"), require("./hmac"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./sha1", "./hmac"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var Base = C_lib.Base;
var WordArray = C_lib.WordArray;
var C_algo = C.algo;
var SHA1 = C_algo.SHA1;
var HMAC = C_algo.HMAC;
/**
* Password-Based Key Derivation Function 2 algorithm.
*/
var PBKDF2 = C_algo.PBKDF2 = Base.extend({
/**
* Configuration options.
*
* @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
* @property {Hasher} hasher The hasher to use. Default: SHA1
* @property {number} iterations The number of iterations to perform. Default: 1
*/
cfg: Base.extend({
keySize: 128/32,
hasher: SHA1,
iterations: 1
}),
/**
* Initializes a newly created key derivation function.
*
* @param {Object} cfg (Optional) The configuration options to use for the derivation.
*
* @example
*
* var kdf = CryptoJS.algo.PBKDF2.create();
* var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 });
* var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 });
*/
init: function (cfg) {
this.cfg = this.cfg.extend(cfg);
},
/**
* Computes the Password-Based Key Derivation Function 2.
*
* @param {WordArray|string} password The password.
* @param {WordArray|string} salt A salt.
*
* @return {WordArray} The derived key.
*
* @example
*
* var key = kdf.compute(password, salt);
*/
compute: function (password, salt) {
// Shortcut
var cfg = this.cfg;
// Init HMAC
var hmac = HMAC.create(cfg.hasher, password);
// Initial values
var derivedKey = WordArray.create();
var blockIndex = WordArray.create([0x00000001]);
// Shortcuts
var derivedKeyWords = derivedKey.words;
var blockIndexWords = blockIndex.words;
var keySize = cfg.keySize;
var iterations = cfg.iterations;
// Generate key
while (derivedKeyWords.length < keySize) {
var block = hmac.update(salt).finalize(blockIndex);
hmac.reset();
// Shortcuts
var blockWords = block.words;
var blockWordsLength = blockWords.length;
// Iterations
var intermediate = block;
for (var i = 1; i < iterations; i++) {
intermediate = hmac.finalize(intermediate);
hmac.reset();
// Shortcut
var intermediateWords = intermediate.words;
// XOR intermediate with block
for (var j = 0; j < blockWordsLength; j++) {
blockWords[j] ^= intermediateWords[j];
}
}
derivedKey.concat(block);
blockIndexWords[0]++;
}
derivedKey.sigBytes = keySize * 4;
return derivedKey;
}
});
/**
* Computes the Password-Based Key Derivation Function 2.
*
* @param {WordArray|string} password The password.
* @param {WordArray|string} salt A salt.
* @param {Object} cfg (Optional) The configuration options to use for this computation.
*
* @return {WordArray} The derived key.
*
* @static
*
* @example
*
* var key = CryptoJS.PBKDF2(password, salt);
* var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 });
* var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 });
*/
C.PBKDF2 = function (password, salt, cfg) {
return PBKDF2.create(cfg).compute(password, salt);
};
}());
return CryptoJS.PBKDF2;
}));

View File

@@ -0,0 +1,190 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var StreamCipher = C_lib.StreamCipher;
var C_algo = C.algo;
// Reusable objects
var S = [];
var C_ = [];
var G = [];
/**
* Rabbit stream cipher algorithm.
*
* This is a legacy version that neglected to convert the key to little-endian.
* This error doesn't affect the cipher's security,
* but it does affect its compatibility with other implementations.
*/
var RabbitLegacy = C_algo.RabbitLegacy = StreamCipher.extend({
_doReset: function () {
// Shortcuts
var K = this._key.words;
var iv = this.cfg.iv;
// Generate initial state values
var X = this._X = [
K[0], (K[3] << 16) | (K[2] >>> 16),
K[1], (K[0] << 16) | (K[3] >>> 16),
K[2], (K[1] << 16) | (K[0] >>> 16),
K[3], (K[2] << 16) | (K[1] >>> 16)
];
// Generate initial counter values
var C = this._C = [
(K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),
(K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),
(K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),
(K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)
];
// Carry bit
this._b = 0;
// Iterate the system four times
for (var i = 0; i < 4; i++) {
nextState.call(this);
}
// Modify the counters
for (var i = 0; i < 8; i++) {
C[i] ^= X[(i + 4) & 7];
}
// IV setup
if (iv) {
// Shortcuts
var IV = iv.words;
var IV_0 = IV[0];
var IV_1 = IV[1];
// Generate four subvectors
var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);
var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);
var i1 = (i0 >>> 16) | (i2 & 0xffff0000);
var i3 = (i2 << 16) | (i0 & 0x0000ffff);
// Modify counter values
C[0] ^= i0;
C[1] ^= i1;
C[2] ^= i2;
C[3] ^= i3;
C[4] ^= i0;
C[5] ^= i1;
C[6] ^= i2;
C[7] ^= i3;
// Iterate the system four times
for (var i = 0; i < 4; i++) {
nextState.call(this);
}
}
},
_doProcessBlock: function (M, offset) {
// Shortcut
var X = this._X;
// Iterate the system
nextState.call(this);
// Generate four keystream words
S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);
S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);
S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);
S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);
for (var i = 0; i < 4; i++) {
// Swap endian
S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) |
(((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00);
// Encrypt
M[offset + i] ^= S[i];
}
},
blockSize: 128/32,
ivSize: 64/32
});
function nextState() {
// Shortcuts
var X = this._X;
var C = this._C;
// Save old counter values
for (var i = 0; i < 8; i++) {
C_[i] = C[i];
}
// Calculate new counter values
C[0] = (C[0] + 0x4d34d34d + this._b) | 0;
C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;
C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;
C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;
C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;
C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;
C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;
C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;
this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;
// Calculate the g-values
for (var i = 0; i < 8; i++) {
var gx = X[i] + C[i];
// Construct high and low argument for squaring
var ga = gx & 0xffff;
var gb = gx >>> 16;
// Calculate high and low result of squaring
var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;
var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);
// High XOR low
G[i] = gh ^ gl;
}
// Calculate new state values
X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;
X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0;
X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;
X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0;
X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;
X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0;
X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;
X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0;
}
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg);
* var plaintext = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg);
*/
C.RabbitLegacy = StreamCipher._createHelper(RabbitLegacy);
}());
return CryptoJS.RabbitLegacy;
}));

View File

@@ -0,0 +1,192 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var StreamCipher = C_lib.StreamCipher;
var C_algo = C.algo;
// Reusable objects
var S = [];
var C_ = [];
var G = [];
/**
* Rabbit stream cipher algorithm
*/
var Rabbit = C_algo.Rabbit = StreamCipher.extend({
_doReset: function () {
// Shortcuts
var K = this._key.words;
var iv = this.cfg.iv;
// Swap endian
for (var i = 0; i < 4; i++) {
K[i] = (((K[i] << 8) | (K[i] >>> 24)) & 0x00ff00ff) |
(((K[i] << 24) | (K[i] >>> 8)) & 0xff00ff00);
}
// Generate initial state values
var X = this._X = [
K[0], (K[3] << 16) | (K[2] >>> 16),
K[1], (K[0] << 16) | (K[3] >>> 16),
K[2], (K[1] << 16) | (K[0] >>> 16),
K[3], (K[2] << 16) | (K[1] >>> 16)
];
// Generate initial counter values
var C = this._C = [
(K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),
(K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),
(K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),
(K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)
];
// Carry bit
this._b = 0;
// Iterate the system four times
for (var i = 0; i < 4; i++) {
nextState.call(this);
}
// Modify the counters
for (var i = 0; i < 8; i++) {
C[i] ^= X[(i + 4) & 7];
}
// IV setup
if (iv) {
// Shortcuts
var IV = iv.words;
var IV_0 = IV[0];
var IV_1 = IV[1];
// Generate four subvectors
var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);
var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);
var i1 = (i0 >>> 16) | (i2 & 0xffff0000);
var i3 = (i2 << 16) | (i0 & 0x0000ffff);
// Modify counter values
C[0] ^= i0;
C[1] ^= i1;
C[2] ^= i2;
C[3] ^= i3;
C[4] ^= i0;
C[5] ^= i1;
C[6] ^= i2;
C[7] ^= i3;
// Iterate the system four times
for (var i = 0; i < 4; i++) {
nextState.call(this);
}
}
},
_doProcessBlock: function (M, offset) {
// Shortcut
var X = this._X;
// Iterate the system
nextState.call(this);
// Generate four keystream words
S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);
S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);
S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);
S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);
for (var i = 0; i < 4; i++) {
// Swap endian
S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) |
(((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00);
// Encrypt
M[offset + i] ^= S[i];
}
},
blockSize: 128/32,
ivSize: 64/32
});
function nextState() {
// Shortcuts
var X = this._X;
var C = this._C;
// Save old counter values
for (var i = 0; i < 8; i++) {
C_[i] = C[i];
}
// Calculate new counter values
C[0] = (C[0] + 0x4d34d34d + this._b) | 0;
C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;
C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;
C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;
C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;
C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;
C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;
C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;
this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;
// Calculate the g-values
for (var i = 0; i < 8; i++) {
var gx = X[i] + C[i];
// Construct high and low argument for squaring
var ga = gx & 0xffff;
var gb = gx >>> 16;
// Calculate high and low result of squaring
var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;
var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);
// High XOR low
G[i] = gh ^ gl;
}
// Calculate new state values
X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;
X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0;
X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;
X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0;
X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;
X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0;
X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;
X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0;
}
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg);
* var plaintext = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg);
*/
C.Rabbit = StreamCipher._createHelper(Rabbit);
}());
return CryptoJS.Rabbit;
}));

139
nx/utils/crypto-js/rc4.js Normal file
View File

@@ -0,0 +1,139 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var StreamCipher = C_lib.StreamCipher;
var C_algo = C.algo;
/**
* RC4 stream cipher algorithm.
*/
var RC4 = C_algo.RC4 = StreamCipher.extend({
_doReset: function () {
// Shortcuts
var key = this._key;
var keyWords = key.words;
var keySigBytes = key.sigBytes;
// Init sbox
var S = this._S = [];
for (var i = 0; i < 256; i++) {
S[i] = i;
}
// Key setup
for (var i = 0, j = 0; i < 256; i++) {
var keyByteIndex = i % keySigBytes;
var keyByte = (keyWords[keyByteIndex >>> 2] >>> (24 - (keyByteIndex % 4) * 8)) & 0xff;
j = (j + S[i] + keyByte) % 256;
// Swap
var t = S[i];
S[i] = S[j];
S[j] = t;
}
// Counters
this._i = this._j = 0;
},
_doProcessBlock: function (M, offset) {
M[offset] ^= generateKeystreamWord.call(this);
},
keySize: 256/32,
ivSize: 0
});
function generateKeystreamWord() {
// Shortcuts
var S = this._S;
var i = this._i;
var j = this._j;
// Generate keystream word
var keystreamWord = 0;
for (var n = 0; n < 4; n++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
// Swap
var t = S[i];
S[i] = S[j];
S[j] = t;
keystreamWord |= S[(S[i] + S[j]) % 256] << (24 - n * 8);
}
// Update counters
this._i = i;
this._j = j;
return keystreamWord;
}
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg);
* var plaintext = CryptoJS.RC4.decrypt(ciphertext, key, cfg);
*/
C.RC4 = StreamCipher._createHelper(RC4);
/**
* Modified RC4 stream cipher algorithm.
*/
var RC4Drop = C_algo.RC4Drop = RC4.extend({
/**
* Configuration options.
*
* @property {number} drop The number of keystream words to drop. Default 192
*/
cfg: RC4.cfg.extend({
drop: 192
}),
_doReset: function () {
RC4._doReset.call(this);
// Drop
for (var i = this.cfg.drop; i > 0; i--) {
generateKeystreamWord.call(this);
}
}
});
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg);
* var plaintext = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg);
*/
C.RC4Drop = StreamCipher._createHelper(RC4Drop);
}());
return CryptoJS.RC4;
}));

View File

@@ -0,0 +1,267 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
/** @preserve
(c) 2012 by Cédric Mesnil. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
(function (Math) {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var Hasher = C_lib.Hasher;
var C_algo = C.algo;
// Constants table
var _zl = WordArray.create([
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13]);
var _zr = WordArray.create([
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]);
var _sl = WordArray.create([
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ]);
var _sr = WordArray.create([
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ]);
var _hl = WordArray.create([ 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]);
var _hr = WordArray.create([ 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]);
/**
* RIPEMD160 hash algorithm.
*/
var RIPEMD160 = C_algo.RIPEMD160 = Hasher.extend({
_doReset: function () {
this._hash = WordArray.create([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);
},
_doProcessBlock: function (M, offset) {
// Swap endian
for (var i = 0; i < 16; i++) {
// Shortcuts
var offset_i = offset + i;
var M_offset_i = M[offset_i];
// Swap
M[offset_i] = (
(((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
(((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
);
}
// Shortcut
var H = this._hash.words;
var hl = _hl.words;
var hr = _hr.words;
var zl = _zl.words;
var zr = _zr.words;
var sl = _sl.words;
var sr = _sr.words;
// Working variables
var al, bl, cl, dl, el;
var ar, br, cr, dr, er;
ar = al = H[0];
br = bl = H[1];
cr = cl = H[2];
dr = dl = H[3];
er = el = H[4];
// Computation
var t;
for (var i = 0; i < 80; i += 1) {
t = (al + M[offset+zl[i]])|0;
if (i<16){
t += f1(bl,cl,dl) + hl[0];
} else if (i<32) {
t += f2(bl,cl,dl) + hl[1];
} else if (i<48) {
t += f3(bl,cl,dl) + hl[2];
} else if (i<64) {
t += f4(bl,cl,dl) + hl[3];
} else {// if (i<80) {
t += f5(bl,cl,dl) + hl[4];
}
t = t|0;
t = rotl(t,sl[i]);
t = (t+el)|0;
al = el;
el = dl;
dl = rotl(cl, 10);
cl = bl;
bl = t;
t = (ar + M[offset+zr[i]])|0;
if (i<16){
t += f5(br,cr,dr) + hr[0];
} else if (i<32) {
t += f4(br,cr,dr) + hr[1];
} else if (i<48) {
t += f3(br,cr,dr) + hr[2];
} else if (i<64) {
t += f2(br,cr,dr) + hr[3];
} else {// if (i<80) {
t += f1(br,cr,dr) + hr[4];
}
t = t|0;
t = rotl(t,sr[i]) ;
t = (t+er)|0;
ar = er;
er = dr;
dr = rotl(cr, 10);
cr = br;
br = t;
}
// Intermediate hash value
t = (H[1] + cl + dr)|0;
H[1] = (H[2] + dl + er)|0;
H[2] = (H[3] + el + ar)|0;
H[3] = (H[4] + al + br)|0;
H[4] = (H[0] + bl + cr)|0;
H[0] = t;
},
_doFinalize: function () {
// Shortcuts
var data = this._data;
var dataWords = data.words;
var nBitsTotal = this._nDataBytes * 8;
var nBitsLeft = data.sigBytes * 8;
// Add padding
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
(((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) |
(((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00)
);
data.sigBytes = (dataWords.length + 1) * 4;
// Hash final blocks
this._process();
// Shortcuts
var hash = this._hash;
var H = hash.words;
// Swap endian
for (var i = 0; i < 5; i++) {
// Shortcut
var H_i = H[i];
// Swap
H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
(((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
}
// Return final computed hash
return hash;
},
clone: function () {
var clone = Hasher.clone.call(this);
clone._hash = this._hash.clone();
return clone;
}
});
function f1(x, y, z) {
return ((x) ^ (y) ^ (z));
}
function f2(x, y, z) {
return (((x)&(y)) | ((~x)&(z)));
}
function f3(x, y, z) {
return (((x) | (~(y))) ^ (z));
}
function f4(x, y, z) {
return (((x) & (z)) | ((y)&(~(z))));
}
function f5(x, y, z) {
return ((x) ^ ((y) |(~(z))));
}
function rotl(x,n) {
return (x<<n) | (x>>>(32-n));
}
/**
* Shortcut function to the hasher's object interface.
*
* @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.RIPEMD160('message');
* var hash = CryptoJS.RIPEMD160(wordArray);
*/
C.RIPEMD160 = Hasher._createHelper(RIPEMD160);
/**
* Shortcut function to the HMAC's object interface.
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacRIPEMD160(message, key);
*/
C.HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160);
}(Math));
return CryptoJS.RIPEMD160;
}));

150
nx/utils/crypto-js/sha1.js Normal file
View File

@@ -0,0 +1,150 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var Hasher = C_lib.Hasher;
var C_algo = C.algo;
// Reusable object
var W = [];
/**
* SHA-1 hash algorithm.
*/
var SHA1 = C_algo.SHA1 = Hasher.extend({
_doReset: function () {
this._hash = new WordArray.init([
0x67452301, 0xefcdab89,
0x98badcfe, 0x10325476,
0xc3d2e1f0
]);
},
_doProcessBlock: function (M, offset) {
// Shortcut
var H = this._hash.words;
// Working variables
var a = H[0];
var b = H[1];
var c = H[2];
var d = H[3];
var e = H[4];
// Computation
for (var i = 0; i < 80; i++) {
if (i < 16) {
W[i] = M[offset + i] | 0;
} else {
var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
W[i] = (n << 1) | (n >>> 31);
}
var t = ((a << 5) | (a >>> 27)) + e + W[i];
if (i < 20) {
t += ((b & c) | (~b & d)) + 0x5a827999;
} else if (i < 40) {
t += (b ^ c ^ d) + 0x6ed9eba1;
} else if (i < 60) {
t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;
} else /* if (i < 80) */ {
t += (b ^ c ^ d) - 0x359d3e2a;
}
e = d;
d = c;
c = (b << 30) | (b >>> 2);
b = a;
a = t;
}
// Intermediate hash value
H[0] = (H[0] + a) | 0;
H[1] = (H[1] + b) | 0;
H[2] = (H[2] + c) | 0;
H[3] = (H[3] + d) | 0;
H[4] = (H[4] + e) | 0;
},
_doFinalize: function () {
// Shortcuts
var data = this._data;
var dataWords = data.words;
var nBitsTotal = this._nDataBytes * 8;
var nBitsLeft = data.sigBytes * 8;
// Add padding
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
data.sigBytes = dataWords.length * 4;
// Hash final blocks
this._process();
// Return final computed hash
return this._hash;
},
clone: function () {
var clone = Hasher.clone.call(this);
clone._hash = this._hash.clone();
return clone;
}
});
/**
* Shortcut function to the hasher's object interface.
*
* @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.SHA1('message');
* var hash = CryptoJS.SHA1(wordArray);
*/
C.SHA1 = Hasher._createHelper(SHA1);
/**
* Shortcut function to the HMAC's object interface.
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacSHA1(message, key);
*/
C.HmacSHA1 = Hasher._createHmacHelper(SHA1);
}());
return CryptoJS.SHA1;
}));

View File

@@ -0,0 +1,80 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./sha256"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./sha256"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var C_algo = C.algo;
var SHA256 = C_algo.SHA256;
/**
* SHA-224 hash algorithm.
*/
var SHA224 = C_algo.SHA224 = SHA256.extend({
_doReset: function () {
this._hash = new WordArray.init([
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
]);
},
_doFinalize: function () {
var hash = SHA256._doFinalize.call(this);
hash.sigBytes -= 4;
return hash;
}
});
/**
* Shortcut function to the hasher's object interface.
*
* @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.SHA224('message');
* var hash = CryptoJS.SHA224(wordArray);
*/
C.SHA224 = SHA256._createHelper(SHA224);
/**
* Shortcut function to the HMAC's object interface.
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacSHA224(message, key);
*/
C.HmacSHA224 = SHA256._createHmacHelper(SHA224);
}());
return CryptoJS.SHA224;
}));

View File

@@ -0,0 +1,199 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function (Math) {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var Hasher = C_lib.Hasher;
var C_algo = C.algo;
// Initialization and round constants tables
var H = [];
var K = [];
// Compute constants
(function () {
function isPrime(n) {
var sqrtN = Math.sqrt(n);
for (var factor = 2; factor <= sqrtN; factor++) {
if (!(n % factor)) {
return false;
}
}
return true;
}
function getFractionalBits(n) {
return ((n - (n | 0)) * 0x100000000) | 0;
}
var n = 2;
var nPrime = 0;
while (nPrime < 64) {
if (isPrime(n)) {
if (nPrime < 8) {
H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
}
K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
nPrime++;
}
n++;
}
}());
// Reusable object
var W = [];
/**
* SHA-256 hash algorithm.
*/
var SHA256 = C_algo.SHA256 = Hasher.extend({
_doReset: function () {
this._hash = new WordArray.init(H.slice(0));
},
_doProcessBlock: function (M, offset) {
// Shortcut
var H = this._hash.words;
// Working variables
var a = H[0];
var b = H[1];
var c = H[2];
var d = H[3];
var e = H[4];
var f = H[5];
var g = H[6];
var h = H[7];
// Computation
for (var i = 0; i < 64; i++) {
if (i < 16) {
W[i] = M[offset + i] | 0;
} else {
var gamma0x = W[i - 15];
var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
((gamma0x << 14) | (gamma0x >>> 18)) ^
(gamma0x >>> 3);
var gamma1x = W[i - 2];
var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
((gamma1x << 13) | (gamma1x >>> 19)) ^
(gamma1x >>> 10);
W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
}
var ch = (e & f) ^ (~e & g);
var maj = (a & b) ^ (a & c) ^ (b & c);
var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));
var t1 = h + sigma1 + ch + K[i] + W[i];
var t2 = sigma0 + maj;
h = g;
g = f;
f = e;
e = (d + t1) | 0;
d = c;
c = b;
b = a;
a = (t1 + t2) | 0;
}
// Intermediate hash value
H[0] = (H[0] + a) | 0;
H[1] = (H[1] + b) | 0;
H[2] = (H[2] + c) | 0;
H[3] = (H[3] + d) | 0;
H[4] = (H[4] + e) | 0;
H[5] = (H[5] + f) | 0;
H[6] = (H[6] + g) | 0;
H[7] = (H[7] + h) | 0;
},
_doFinalize: function () {
// Shortcuts
var data = this._data;
var dataWords = data.words;
var nBitsTotal = this._nDataBytes * 8;
var nBitsLeft = data.sigBytes * 8;
// Add padding
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
data.sigBytes = dataWords.length * 4;
// Hash final blocks
this._process();
// Return final computed hash
return this._hash;
},
clone: function () {
var clone = Hasher.clone.call(this);
clone._hash = this._hash.clone();
return clone;
}
});
/**
* Shortcut function to the hasher's object interface.
*
* @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.SHA256('message');
* var hash = CryptoJS.SHA256(wordArray);
*/
C.SHA256 = Hasher._createHelper(SHA256);
/**
* Shortcut function to the HMAC's object interface.
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacSHA256(message, key);
*/
C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
}(Math));
return CryptoJS.SHA256;
}));

326
nx/utils/crypto-js/sha3.js Normal file
View File

@@ -0,0 +1,326 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./x64-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./x64-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function (Math) {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var Hasher = C_lib.Hasher;
var C_x64 = C.x64;
var X64Word = C_x64.Word;
var C_algo = C.algo;
// Constants tables
var RHO_OFFSETS = [];
var PI_INDEXES = [];
var ROUND_CONSTANTS = [];
// Compute Constants
(function () {
// Compute rho offset constants
var x = 1, y = 0;
for (var t = 0; t < 24; t++) {
RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64;
var newX = y % 5;
var newY = (2 * x + 3 * y) % 5;
x = newX;
y = newY;
}
// Compute pi index constants
for (var x = 0; x < 5; x++) {
for (var y = 0; y < 5; y++) {
PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5;
}
}
// Compute round constants
var LFSR = 0x01;
for (var i = 0; i < 24; i++) {
var roundConstantMsw = 0;
var roundConstantLsw = 0;
for (var j = 0; j < 7; j++) {
if (LFSR & 0x01) {
var bitPosition = (1 << j) - 1;
if (bitPosition < 32) {
roundConstantLsw ^= 1 << bitPosition;
} else /* if (bitPosition >= 32) */ {
roundConstantMsw ^= 1 << (bitPosition - 32);
}
}
// Compute next LFSR
if (LFSR & 0x80) {
// Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1
LFSR = (LFSR << 1) ^ 0x71;
} else {
LFSR <<= 1;
}
}
ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw);
}
}());
// Reusable objects for temporary values
var T = [];
(function () {
for (var i = 0; i < 25; i++) {
T[i] = X64Word.create();
}
}());
/**
* SHA-3 hash algorithm.
*/
var SHA3 = C_algo.SHA3 = Hasher.extend({
/**
* Configuration options.
*
* @property {number} outputLength
* The desired number of bits in the output hash.
* Only values permitted are: 224, 256, 384, 512.
* Default: 512
*/
cfg: Hasher.cfg.extend({
outputLength: 512
}),
_doReset: function () {
var state = this._state = []
for (var i = 0; i < 25; i++) {
state[i] = new X64Word.init();
}
this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32;
},
_doProcessBlock: function (M, offset) {
// Shortcuts
var state = this._state;
var nBlockSizeLanes = this.blockSize / 2;
// Absorb
for (var i = 0; i < nBlockSizeLanes; i++) {
// Shortcuts
var M2i = M[offset + 2 * i];
var M2i1 = M[offset + 2 * i + 1];
// Swap endian
M2i = (
(((M2i << 8) | (M2i >>> 24)) & 0x00ff00ff) |
(((M2i << 24) | (M2i >>> 8)) & 0xff00ff00)
);
M2i1 = (
(((M2i1 << 8) | (M2i1 >>> 24)) & 0x00ff00ff) |
(((M2i1 << 24) | (M2i1 >>> 8)) & 0xff00ff00)
);
// Absorb message into state
var lane = state[i];
lane.high ^= M2i1;
lane.low ^= M2i;
}
// Rounds
for (var round = 0; round < 24; round++) {
// Theta
for (var x = 0; x < 5; x++) {
// Mix column lanes
var tMsw = 0, tLsw = 0;
for (var y = 0; y < 5; y++) {
var lane = state[x + 5 * y];
tMsw ^= lane.high;
tLsw ^= lane.low;
}
// Temporary values
var Tx = T[x];
Tx.high = tMsw;
Tx.low = tLsw;
}
for (var x = 0; x < 5; x++) {
// Shortcuts
var Tx4 = T[(x + 4) % 5];
var Tx1 = T[(x + 1) % 5];
var Tx1Msw = Tx1.high;
var Tx1Lsw = Tx1.low;
// Mix surrounding columns
var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31));
var tLsw = Tx4.low ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31));
for (var y = 0; y < 5; y++) {
var lane = state[x + 5 * y];
lane.high ^= tMsw;
lane.low ^= tLsw;
}
}
// Rho Pi
for (var laneIndex = 1; laneIndex < 25; laneIndex++) {
var tMsw;
var tLsw;
// Shortcuts
var lane = state[laneIndex];
var laneMsw = lane.high;
var laneLsw = lane.low;
var rhoOffset = RHO_OFFSETS[laneIndex];
// Rotate lanes
if (rhoOffset < 32) {
tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset));
tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset));
} else /* if (rhoOffset >= 32) */ {
tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset));
tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset));
}
// Transpose lanes
var TPiLane = T[PI_INDEXES[laneIndex]];
TPiLane.high = tMsw;
TPiLane.low = tLsw;
}
// Rho pi at x = y = 0
var T0 = T[0];
var state0 = state[0];
T0.high = state0.high;
T0.low = state0.low;
// Chi
for (var x = 0; x < 5; x++) {
for (var y = 0; y < 5; y++) {
// Shortcuts
var laneIndex = x + 5 * y;
var lane = state[laneIndex];
var TLane = T[laneIndex];
var Tx1Lane = T[((x + 1) % 5) + 5 * y];
var Tx2Lane = T[((x + 2) % 5) + 5 * y];
// Mix rows
lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high);
lane.low = TLane.low ^ (~Tx1Lane.low & Tx2Lane.low);
}
}
// Iota
var lane = state[0];
var roundConstant = ROUND_CONSTANTS[round];
lane.high ^= roundConstant.high;
lane.low ^= roundConstant.low;
}
},
_doFinalize: function () {
// Shortcuts
var data = this._data;
var dataWords = data.words;
var nBitsTotal = this._nDataBytes * 8;
var nBitsLeft = data.sigBytes * 8;
var blockSizeBits = this.blockSize * 32;
// Add padding
dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32);
dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80;
data.sigBytes = dataWords.length * 4;
// Hash final blocks
this._process();
// Shortcuts
var state = this._state;
var outputLengthBytes = this.cfg.outputLength / 8;
var outputLengthLanes = outputLengthBytes / 8;
// Squeeze
var hashWords = [];
for (var i = 0; i < outputLengthLanes; i++) {
// Shortcuts
var lane = state[i];
var laneMsw = lane.high;
var laneLsw = lane.low;
// Swap endian
laneMsw = (
(((laneMsw << 8) | (laneMsw >>> 24)) & 0x00ff00ff) |
(((laneMsw << 24) | (laneMsw >>> 8)) & 0xff00ff00)
);
laneLsw = (
(((laneLsw << 8) | (laneLsw >>> 24)) & 0x00ff00ff) |
(((laneLsw << 24) | (laneLsw >>> 8)) & 0xff00ff00)
);
// Squeeze state to retrieve hash
hashWords.push(laneLsw);
hashWords.push(laneMsw);
}
// Return final computed hash
return new WordArray.init(hashWords, outputLengthBytes);
},
clone: function () {
var clone = Hasher.clone.call(this);
var state = clone._state = this._state.slice(0);
for (var i = 0; i < 25; i++) {
state[i] = state[i].clone();
}
return clone;
}
});
/**
* Shortcut function to the hasher's object interface.
*
* @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.SHA3('message');
* var hash = CryptoJS.SHA3(wordArray);
*/
C.SHA3 = Hasher._createHelper(SHA3);
/**
* Shortcut function to the HMAC's object interface.
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacSHA3(message, key);
*/
C.HmacSHA3 = Hasher._createHmacHelper(SHA3);
}(Math));
return CryptoJS.SHA3;
}));

View File

@@ -0,0 +1,83 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./x64-core"), require("./sha512"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./x64-core", "./sha512"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_x64 = C.x64;
var X64Word = C_x64.Word;
var X64WordArray = C_x64.WordArray;
var C_algo = C.algo;
var SHA512 = C_algo.SHA512;
/**
* SHA-384 hash algorithm.
*/
var SHA384 = C_algo.SHA384 = SHA512.extend({
_doReset: function () {
this._hash = new X64WordArray.init([
new X64Word.init(0xcbbb9d5d, 0xc1059ed8), new X64Word.init(0x629a292a, 0x367cd507),
new X64Word.init(0x9159015a, 0x3070dd17), new X64Word.init(0x152fecd8, 0xf70e5939),
new X64Word.init(0x67332667, 0xffc00b31), new X64Word.init(0x8eb44a87, 0x68581511),
new X64Word.init(0xdb0c2e0d, 0x64f98fa7), new X64Word.init(0x47b5481d, 0xbefa4fa4)
]);
},
_doFinalize: function () {
var hash = SHA512._doFinalize.call(this);
hash.sigBytes -= 16;
return hash;
}
});
/**
* Shortcut function to the hasher's object interface.
*
* @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.SHA384('message');
* var hash = CryptoJS.SHA384(wordArray);
*/
C.SHA384 = SHA512._createHelper(SHA384);
/**
* Shortcut function to the HMAC's object interface.
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacSHA384(message, key);
*/
C.HmacSHA384 = SHA512._createHmacHelper(SHA384);
}());
return CryptoJS.SHA384;
}));

View File

@@ -0,0 +1,326 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./x64-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./x64-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var Hasher = C_lib.Hasher;
var C_x64 = C.x64;
var X64Word = C_x64.Word;
var X64WordArray = C_x64.WordArray;
var C_algo = C.algo;
function X64Word_create() {
return X64Word.create.apply(X64Word, arguments);
}
// Constants
var K = [
X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd),
X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc),
X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019),
X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118),
X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe),
X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2),
X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1),
X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694),
X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3),
X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65),
X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483),
X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5),
X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210),
X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4),
X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725),
X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70),
X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926),
X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df),
X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8),
X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b),
X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001),
X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30),
X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910),
X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8),
X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53),
X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8),
X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb),
X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3),
X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60),
X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec),
X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9),
X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b),
X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207),
X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178),
X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6),
X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b),
X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493),
X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c),
X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a),
X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817)
];
// Reusable objects
var W = [];
(function () {
for (var i = 0; i < 80; i++) {
W[i] = X64Word_create();
}
}());
/**
* SHA-512 hash algorithm.
*/
var SHA512 = C_algo.SHA512 = Hasher.extend({
_doReset: function () {
this._hash = new X64WordArray.init([
new X64Word.init(0x6a09e667, 0xf3bcc908), new X64Word.init(0xbb67ae85, 0x84caa73b),
new X64Word.init(0x3c6ef372, 0xfe94f82b), new X64Word.init(0xa54ff53a, 0x5f1d36f1),
new X64Word.init(0x510e527f, 0xade682d1), new X64Word.init(0x9b05688c, 0x2b3e6c1f),
new X64Word.init(0x1f83d9ab, 0xfb41bd6b), new X64Word.init(0x5be0cd19, 0x137e2179)
]);
},
_doProcessBlock: function (M, offset) {
// Shortcuts
var H = this._hash.words;
var H0 = H[0];
var H1 = H[1];
var H2 = H[2];
var H3 = H[3];
var H4 = H[4];
var H5 = H[5];
var H6 = H[6];
var H7 = H[7];
var H0h = H0.high;
var H0l = H0.low;
var H1h = H1.high;
var H1l = H1.low;
var H2h = H2.high;
var H2l = H2.low;
var H3h = H3.high;
var H3l = H3.low;
var H4h = H4.high;
var H4l = H4.low;
var H5h = H5.high;
var H5l = H5.low;
var H6h = H6.high;
var H6l = H6.low;
var H7h = H7.high;
var H7l = H7.low;
// Working variables
var ah = H0h;
var al = H0l;
var bh = H1h;
var bl = H1l;
var ch = H2h;
var cl = H2l;
var dh = H3h;
var dl = H3l;
var eh = H4h;
var el = H4l;
var fh = H5h;
var fl = H5l;
var gh = H6h;
var gl = H6l;
var hh = H7h;
var hl = H7l;
// Rounds
for (var i = 0; i < 80; i++) {
var Wil;
var Wih;
// Shortcut
var Wi = W[i];
// Extend message
if (i < 16) {
Wih = Wi.high = M[offset + i * 2] | 0;
Wil = Wi.low = M[offset + i * 2 + 1] | 0;
} else {
// Gamma0
var gamma0x = W[i - 15];
var gamma0xh = gamma0x.high;
var gamma0xl = gamma0x.low;
var gamma0h = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7);
var gamma0l = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25));
// Gamma1
var gamma1x = W[i - 2];
var gamma1xh = gamma1x.high;
var gamma1xl = gamma1x.low;
var gamma1h = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6);
var gamma1l = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26));
// W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
var Wi7 = W[i - 7];
var Wi7h = Wi7.high;
var Wi7l = Wi7.low;
var Wi16 = W[i - 16];
var Wi16h = Wi16.high;
var Wi16l = Wi16.low;
Wil = gamma0l + Wi7l;
Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0);
Wil = Wil + gamma1l;
Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0);
Wil = Wil + Wi16l;
Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0);
Wi.high = Wih;
Wi.low = Wil;
}
var chh = (eh & fh) ^ (~eh & gh);
var chl = (el & fl) ^ (~el & gl);
var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch);
var majl = (al & bl) ^ (al & cl) ^ (bl & cl);
var sigma0h = ((ah >>> 28) | (al << 4)) ^ ((ah << 30) | (al >>> 2)) ^ ((ah << 25) | (al >>> 7));
var sigma0l = ((al >>> 28) | (ah << 4)) ^ ((al << 30) | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7));
var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9));
var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9));
// t1 = h + sigma1 + ch + K[i] + W[i]
var Ki = K[i];
var Kih = Ki.high;
var Kil = Ki.low;
var t1l = hl + sigma1l;
var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0);
var t1l = t1l + chl;
var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0);
var t1l = t1l + Kil;
var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0);
var t1l = t1l + Wil;
var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0);
// t2 = sigma0 + maj
var t2l = sigma0l + majl;
var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0);
// Update working variables
hh = gh;
hl = gl;
gh = fh;
gl = fl;
fh = eh;
fl = el;
el = (dl + t1l) | 0;
eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0;
dh = ch;
dl = cl;
ch = bh;
cl = bl;
bh = ah;
bl = al;
al = (t1l + t2l) | 0;
ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0;
}
// Intermediate hash value
H0l = H0.low = (H0l + al);
H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0));
H1l = H1.low = (H1l + bl);
H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0));
H2l = H2.low = (H2l + cl);
H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0));
H3l = H3.low = (H3l + dl);
H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0));
H4l = H4.low = (H4l + el);
H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0));
H5l = H5.low = (H5l + fl);
H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0));
H6l = H6.low = (H6l + gl);
H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0));
H7l = H7.low = (H7l + hl);
H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0));
},
_doFinalize: function () {
// Shortcuts
var data = this._data;
var dataWords = data.words;
var nBitsTotal = this._nDataBytes * 8;
var nBitsLeft = data.sigBytes * 8;
// Add padding
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 30] = Math.floor(nBitsTotal / 0x100000000);
dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal;
data.sigBytes = dataWords.length * 4;
// Hash final blocks
this._process();
// Convert hash to 32-bit word array before returning
var hash = this._hash.toX32();
// Return final computed hash
return hash;
},
clone: function () {
var clone = Hasher.clone.call(this);
clone._hash = this._hash.clone();
return clone;
},
blockSize: 1024/32
});
/**
* Shortcut function to the hasher's object interface.
*
* @param {WordArray|string} message The message to hash.
*
* @return {WordArray} The hash.
*
* @static
*
* @example
*
* var hash = CryptoJS.SHA512('message');
* var hash = CryptoJS.SHA512(wordArray);
*/
C.SHA512 = Hasher._createHelper(SHA512);
/**
* Shortcut function to the HMAC's object interface.
*
* @param {WordArray|string} message The message to hash.
* @param {WordArray|string} key The secret key.
*
* @return {WordArray} The HMAC.
*
* @static
*
* @example
*
* var hmac = CryptoJS.HmacSHA512(message, key);
*/
C.HmacSHA512 = Hasher._createHmacHelper(SHA512);
}());
return CryptoJS.SHA512;
}));

View File

@@ -0,0 +1,779 @@
;(function (root, factory, undef) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var BlockCipher = C_lib.BlockCipher;
var C_algo = C.algo;
// Permuted Choice 1 constants
var PC1 = [
57, 49, 41, 33, 25, 17, 9, 1,
58, 50, 42, 34, 26, 18, 10, 2,
59, 51, 43, 35, 27, 19, 11, 3,
60, 52, 44, 36, 63, 55, 47, 39,
31, 23, 15, 7, 62, 54, 46, 38,
30, 22, 14, 6, 61, 53, 45, 37,
29, 21, 13, 5, 28, 20, 12, 4
];
// Permuted Choice 2 constants
var PC2 = [
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
];
// Cumulative bit shift constants
var BIT_SHIFTS = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28];
// SBOXes and round permutation constants
var SBOX_P = [
{
0x0: 0x808200,
0x10000000: 0x8000,
0x20000000: 0x808002,
0x30000000: 0x2,
0x40000000: 0x200,
0x50000000: 0x808202,
0x60000000: 0x800202,
0x70000000: 0x800000,
0x80000000: 0x202,
0x90000000: 0x800200,
0xa0000000: 0x8200,
0xb0000000: 0x808000,
0xc0000000: 0x8002,
0xd0000000: 0x800002,
0xe0000000: 0x0,
0xf0000000: 0x8202,
0x8000000: 0x0,
0x18000000: 0x808202,
0x28000000: 0x8202,
0x38000000: 0x8000,
0x48000000: 0x808200,
0x58000000: 0x200,
0x68000000: 0x808002,
0x78000000: 0x2,
0x88000000: 0x800200,
0x98000000: 0x8200,
0xa8000000: 0x808000,
0xb8000000: 0x800202,
0xc8000000: 0x800002,
0xd8000000: 0x8002,
0xe8000000: 0x202,
0xf8000000: 0x800000,
0x1: 0x8000,
0x10000001: 0x2,
0x20000001: 0x808200,
0x30000001: 0x800000,
0x40000001: 0x808002,
0x50000001: 0x8200,
0x60000001: 0x200,
0x70000001: 0x800202,
0x80000001: 0x808202,
0x90000001: 0x808000,
0xa0000001: 0x800002,
0xb0000001: 0x8202,
0xc0000001: 0x202,
0xd0000001: 0x800200,
0xe0000001: 0x8002,
0xf0000001: 0x0,
0x8000001: 0x808202,
0x18000001: 0x808000,
0x28000001: 0x800000,
0x38000001: 0x200,
0x48000001: 0x8000,
0x58000001: 0x800002,
0x68000001: 0x2,
0x78000001: 0x8202,
0x88000001: 0x8002,
0x98000001: 0x800202,
0xa8000001: 0x202,
0xb8000001: 0x808200,
0xc8000001: 0x800200,
0xd8000001: 0x0,
0xe8000001: 0x8200,
0xf8000001: 0x808002
},
{
0x0: 0x40084010,
0x1000000: 0x4000,
0x2000000: 0x80000,
0x3000000: 0x40080010,
0x4000000: 0x40000010,
0x5000000: 0x40084000,
0x6000000: 0x40004000,
0x7000000: 0x10,
0x8000000: 0x84000,
0x9000000: 0x40004010,
0xa000000: 0x40000000,
0xb000000: 0x84010,
0xc000000: 0x80010,
0xd000000: 0x0,
0xe000000: 0x4010,
0xf000000: 0x40080000,
0x800000: 0x40004000,
0x1800000: 0x84010,
0x2800000: 0x10,
0x3800000: 0x40004010,
0x4800000: 0x40084010,
0x5800000: 0x40000000,
0x6800000: 0x80000,
0x7800000: 0x40080010,
0x8800000: 0x80010,
0x9800000: 0x0,
0xa800000: 0x4000,
0xb800000: 0x40080000,
0xc800000: 0x40000010,
0xd800000: 0x84000,
0xe800000: 0x40084000,
0xf800000: 0x4010,
0x10000000: 0x0,
0x11000000: 0x40080010,
0x12000000: 0x40004010,
0x13000000: 0x40084000,
0x14000000: 0x40080000,
0x15000000: 0x10,
0x16000000: 0x84010,
0x17000000: 0x4000,
0x18000000: 0x4010,
0x19000000: 0x80000,
0x1a000000: 0x80010,
0x1b000000: 0x40000010,
0x1c000000: 0x84000,
0x1d000000: 0x40004000,
0x1e000000: 0x40000000,
0x1f000000: 0x40084010,
0x10800000: 0x84010,
0x11800000: 0x80000,
0x12800000: 0x40080000,
0x13800000: 0x4000,
0x14800000: 0x40004000,
0x15800000: 0x40084010,
0x16800000: 0x10,
0x17800000: 0x40000000,
0x18800000: 0x40084000,
0x19800000: 0x40000010,
0x1a800000: 0x40004010,
0x1b800000: 0x80010,
0x1c800000: 0x0,
0x1d800000: 0x4010,
0x1e800000: 0x40080010,
0x1f800000: 0x84000
},
{
0x0: 0x104,
0x100000: 0x0,
0x200000: 0x4000100,
0x300000: 0x10104,
0x400000: 0x10004,
0x500000: 0x4000004,
0x600000: 0x4010104,
0x700000: 0x4010000,
0x800000: 0x4000000,
0x900000: 0x4010100,
0xa00000: 0x10100,
0xb00000: 0x4010004,
0xc00000: 0x4000104,
0xd00000: 0x10000,
0xe00000: 0x4,
0xf00000: 0x100,
0x80000: 0x4010100,
0x180000: 0x4010004,
0x280000: 0x0,
0x380000: 0x4000100,
0x480000: 0x4000004,
0x580000: 0x10000,
0x680000: 0x10004,
0x780000: 0x104,
0x880000: 0x4,
0x980000: 0x100,
0xa80000: 0x4010000,
0xb80000: 0x10104,
0xc80000: 0x10100,
0xd80000: 0x4000104,
0xe80000: 0x4010104,
0xf80000: 0x4000000,
0x1000000: 0x4010100,
0x1100000: 0x10004,
0x1200000: 0x10000,
0x1300000: 0x4000100,
0x1400000: 0x100,
0x1500000: 0x4010104,
0x1600000: 0x4000004,
0x1700000: 0x0,
0x1800000: 0x4000104,
0x1900000: 0x4000000,
0x1a00000: 0x4,
0x1b00000: 0x10100,
0x1c00000: 0x4010000,
0x1d00000: 0x104,
0x1e00000: 0x10104,
0x1f00000: 0x4010004,
0x1080000: 0x4000000,
0x1180000: 0x104,
0x1280000: 0x4010100,
0x1380000: 0x0,
0x1480000: 0x10004,
0x1580000: 0x4000100,
0x1680000: 0x100,
0x1780000: 0x4010004,
0x1880000: 0x10000,
0x1980000: 0x4010104,
0x1a80000: 0x10104,
0x1b80000: 0x4000004,
0x1c80000: 0x4000104,
0x1d80000: 0x4010000,
0x1e80000: 0x4,
0x1f80000: 0x10100
},
{
0x0: 0x80401000,
0x10000: 0x80001040,
0x20000: 0x401040,
0x30000: 0x80400000,
0x40000: 0x0,
0x50000: 0x401000,
0x60000: 0x80000040,
0x70000: 0x400040,
0x80000: 0x80000000,
0x90000: 0x400000,
0xa0000: 0x40,
0xb0000: 0x80001000,
0xc0000: 0x80400040,
0xd0000: 0x1040,
0xe0000: 0x1000,
0xf0000: 0x80401040,
0x8000: 0x80001040,
0x18000: 0x40,
0x28000: 0x80400040,
0x38000: 0x80001000,
0x48000: 0x401000,
0x58000: 0x80401040,
0x68000: 0x0,
0x78000: 0x80400000,
0x88000: 0x1000,
0x98000: 0x80401000,
0xa8000: 0x400000,
0xb8000: 0x1040,
0xc8000: 0x80000000,
0xd8000: 0x400040,
0xe8000: 0x401040,
0xf8000: 0x80000040,
0x100000: 0x400040,
0x110000: 0x401000,
0x120000: 0x80000040,
0x130000: 0x0,
0x140000: 0x1040,
0x150000: 0x80400040,
0x160000: 0x80401000,
0x170000: 0x80001040,
0x180000: 0x80401040,
0x190000: 0x80000000,
0x1a0000: 0x80400000,
0x1b0000: 0x401040,
0x1c0000: 0x80001000,
0x1d0000: 0x400000,
0x1e0000: 0x40,
0x1f0000: 0x1000,
0x108000: 0x80400000,
0x118000: 0x80401040,
0x128000: 0x0,
0x138000: 0x401000,
0x148000: 0x400040,
0x158000: 0x80000000,
0x168000: 0x80001040,
0x178000: 0x40,
0x188000: 0x80000040,
0x198000: 0x1000,
0x1a8000: 0x80001000,
0x1b8000: 0x80400040,
0x1c8000: 0x1040,
0x1d8000: 0x80401000,
0x1e8000: 0x400000,
0x1f8000: 0x401040
},
{
0x0: 0x80,
0x1000: 0x1040000,
0x2000: 0x40000,
0x3000: 0x20000000,
0x4000: 0x20040080,
0x5000: 0x1000080,
0x6000: 0x21000080,
0x7000: 0x40080,
0x8000: 0x1000000,
0x9000: 0x20040000,
0xa000: 0x20000080,
0xb000: 0x21040080,
0xc000: 0x21040000,
0xd000: 0x0,
0xe000: 0x1040080,
0xf000: 0x21000000,
0x800: 0x1040080,
0x1800: 0x21000080,
0x2800: 0x80,
0x3800: 0x1040000,
0x4800: 0x40000,
0x5800: 0x20040080,
0x6800: 0x21040000,
0x7800: 0x20000000,
0x8800: 0x20040000,
0x9800: 0x0,
0xa800: 0x21040080,
0xb800: 0x1000080,
0xc800: 0x20000080,
0xd800: 0x21000000,
0xe800: 0x1000000,
0xf800: 0x40080,
0x10000: 0x40000,
0x11000: 0x80,
0x12000: 0x20000000,
0x13000: 0x21000080,
0x14000: 0x1000080,
0x15000: 0x21040000,
0x16000: 0x20040080,
0x17000: 0x1000000,
0x18000: 0x21040080,
0x19000: 0x21000000,
0x1a000: 0x1040000,
0x1b000: 0x20040000,
0x1c000: 0x40080,
0x1d000: 0x20000080,
0x1e000: 0x0,
0x1f000: 0x1040080,
0x10800: 0x21000080,
0x11800: 0x1000000,
0x12800: 0x1040000,
0x13800: 0x20040080,
0x14800: 0x20000000,
0x15800: 0x1040080,
0x16800: 0x80,
0x17800: 0x21040000,
0x18800: 0x40080,
0x19800: 0x21040080,
0x1a800: 0x0,
0x1b800: 0x21000000,
0x1c800: 0x1000080,
0x1d800: 0x40000,
0x1e800: 0x20040000,
0x1f800: 0x20000080
},
{
0x0: 0x10000008,
0x100: 0x2000,
0x200: 0x10200000,
0x300: 0x10202008,
0x400: 0x10002000,
0x500: 0x200000,
0x600: 0x200008,
0x700: 0x10000000,
0x800: 0x0,
0x900: 0x10002008,
0xa00: 0x202000,
0xb00: 0x8,
0xc00: 0x10200008,
0xd00: 0x202008,
0xe00: 0x2008,
0xf00: 0x10202000,
0x80: 0x10200000,
0x180: 0x10202008,
0x280: 0x8,
0x380: 0x200000,
0x480: 0x202008,
0x580: 0x10000008,
0x680: 0x10002000,
0x780: 0x2008,
0x880: 0x200008,
0x980: 0x2000,
0xa80: 0x10002008,
0xb80: 0x10200008,
0xc80: 0x0,
0xd80: 0x10202000,
0xe80: 0x202000,
0xf80: 0x10000000,
0x1000: 0x10002000,
0x1100: 0x10200008,
0x1200: 0x10202008,
0x1300: 0x2008,
0x1400: 0x200000,
0x1500: 0x10000000,
0x1600: 0x10000008,
0x1700: 0x202000,
0x1800: 0x202008,
0x1900: 0x0,
0x1a00: 0x8,
0x1b00: 0x10200000,
0x1c00: 0x2000,
0x1d00: 0x10002008,
0x1e00: 0x10202000,
0x1f00: 0x200008,
0x1080: 0x8,
0x1180: 0x202000,
0x1280: 0x200000,
0x1380: 0x10000008,
0x1480: 0x10002000,
0x1580: 0x2008,
0x1680: 0x10202008,
0x1780: 0x10200000,
0x1880: 0x10202000,
0x1980: 0x10200008,
0x1a80: 0x2000,
0x1b80: 0x202008,
0x1c80: 0x200008,
0x1d80: 0x0,
0x1e80: 0x10000000,
0x1f80: 0x10002008
},
{
0x0: 0x100000,
0x10: 0x2000401,
0x20: 0x400,
0x30: 0x100401,
0x40: 0x2100401,
0x50: 0x0,
0x60: 0x1,
0x70: 0x2100001,
0x80: 0x2000400,
0x90: 0x100001,
0xa0: 0x2000001,
0xb0: 0x2100400,
0xc0: 0x2100000,
0xd0: 0x401,
0xe0: 0x100400,
0xf0: 0x2000000,
0x8: 0x2100001,
0x18: 0x0,
0x28: 0x2000401,
0x38: 0x2100400,
0x48: 0x100000,
0x58: 0x2000001,
0x68: 0x2000000,
0x78: 0x401,
0x88: 0x100401,
0x98: 0x2000400,
0xa8: 0x2100000,
0xb8: 0x100001,
0xc8: 0x400,
0xd8: 0x2100401,
0xe8: 0x1,
0xf8: 0x100400,
0x100: 0x2000000,
0x110: 0x100000,
0x120: 0x2000401,
0x130: 0x2100001,
0x140: 0x100001,
0x150: 0x2000400,
0x160: 0x2100400,
0x170: 0x100401,
0x180: 0x401,
0x190: 0x2100401,
0x1a0: 0x100400,
0x1b0: 0x1,
0x1c0: 0x0,
0x1d0: 0x2100000,
0x1e0: 0x2000001,
0x1f0: 0x400,
0x108: 0x100400,
0x118: 0x2000401,
0x128: 0x2100001,
0x138: 0x1,
0x148: 0x2000000,
0x158: 0x100000,
0x168: 0x401,
0x178: 0x2100400,
0x188: 0x2000001,
0x198: 0x2100000,
0x1a8: 0x0,
0x1b8: 0x2100401,
0x1c8: 0x100401,
0x1d8: 0x400,
0x1e8: 0x2000400,
0x1f8: 0x100001
},
{
0x0: 0x8000820,
0x1: 0x20000,
0x2: 0x8000000,
0x3: 0x20,
0x4: 0x20020,
0x5: 0x8020820,
0x6: 0x8020800,
0x7: 0x800,
0x8: 0x8020000,
0x9: 0x8000800,
0xa: 0x20800,
0xb: 0x8020020,
0xc: 0x820,
0xd: 0x0,
0xe: 0x8000020,
0xf: 0x20820,
0x80000000: 0x800,
0x80000001: 0x8020820,
0x80000002: 0x8000820,
0x80000003: 0x8000000,
0x80000004: 0x8020000,
0x80000005: 0x20800,
0x80000006: 0x20820,
0x80000007: 0x20,
0x80000008: 0x8000020,
0x80000009: 0x820,
0x8000000a: 0x20020,
0x8000000b: 0x8020800,
0x8000000c: 0x0,
0x8000000d: 0x8020020,
0x8000000e: 0x8000800,
0x8000000f: 0x20000,
0x10: 0x20820,
0x11: 0x8020800,
0x12: 0x20,
0x13: 0x800,
0x14: 0x8000800,
0x15: 0x8000020,
0x16: 0x8020020,
0x17: 0x20000,
0x18: 0x0,
0x19: 0x20020,
0x1a: 0x8020000,
0x1b: 0x8000820,
0x1c: 0x8020820,
0x1d: 0x20800,
0x1e: 0x820,
0x1f: 0x8000000,
0x80000010: 0x20000,
0x80000011: 0x800,
0x80000012: 0x8020020,
0x80000013: 0x20820,
0x80000014: 0x20,
0x80000015: 0x8020000,
0x80000016: 0x8000000,
0x80000017: 0x8000820,
0x80000018: 0x8020820,
0x80000019: 0x8000020,
0x8000001a: 0x8000800,
0x8000001b: 0x0,
0x8000001c: 0x20800,
0x8000001d: 0x820,
0x8000001e: 0x20020,
0x8000001f: 0x8020800
}
];
// Masks that select the SBOX input
var SBOX_MASK = [
0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,
0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f
];
/**
* DES block cipher algorithm.
*/
var DES = C_algo.DES = BlockCipher.extend({
_doReset: function () {
// Shortcuts
var key = this._key;
var keyWords = key.words;
// Select 56 bits according to PC1
var keyBits = [];
for (var i = 0; i < 56; i++) {
var keyBitPos = PC1[i] - 1;
keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1;
}
// Assemble 16 subkeys
var subKeys = this._subKeys = [];
for (var nSubKey = 0; nSubKey < 16; nSubKey++) {
// Create subkey
var subKey = subKeys[nSubKey] = [];
// Shortcut
var bitShift = BIT_SHIFTS[nSubKey];
// Select 48 bits according to PC2
for (var i = 0; i < 24; i++) {
// Select from the left 28 key bits
subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6);
// Select from the right 28 key bits
subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6);
}
// Since each subkey is applied to an expanded 32-bit input,
// the subkey can be broken into 8 values scaled to 32-bits,
// which allows the key to be used without expansion
subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31);
for (var i = 1; i < 7; i++) {
subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3);
}
subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27);
}
// Compute inverse subkeys
var invSubKeys = this._invSubKeys = [];
for (var i = 0; i < 16; i++) {
invSubKeys[i] = subKeys[15 - i];
}
},
encryptBlock: function (M, offset) {
this._doCryptBlock(M, offset, this._subKeys);
},
decryptBlock: function (M, offset) {
this._doCryptBlock(M, offset, this._invSubKeys);
},
_doCryptBlock: function (M, offset, subKeys) {
// Get input
this._lBlock = M[offset];
this._rBlock = M[offset + 1];
// Initial permutation
exchangeLR.call(this, 4, 0x0f0f0f0f);
exchangeLR.call(this, 16, 0x0000ffff);
exchangeRL.call(this, 2, 0x33333333);
exchangeRL.call(this, 8, 0x00ff00ff);
exchangeLR.call(this, 1, 0x55555555);
// Rounds
for (var round = 0; round < 16; round++) {
// Shortcuts
var subKey = subKeys[round];
var lBlock = this._lBlock;
var rBlock = this._rBlock;
// Feistel function
var f = 0;
for (var i = 0; i < 8; i++) {
f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0];
}
this._lBlock = rBlock;
this._rBlock = lBlock ^ f;
}
// Undo swap from last round
var t = this._lBlock;
this._lBlock = this._rBlock;
this._rBlock = t;
// Final permutation
exchangeLR.call(this, 1, 0x55555555);
exchangeRL.call(this, 8, 0x00ff00ff);
exchangeRL.call(this, 2, 0x33333333);
exchangeLR.call(this, 16, 0x0000ffff);
exchangeLR.call(this, 4, 0x0f0f0f0f);
// Set output
M[offset] = this._lBlock;
M[offset + 1] = this._rBlock;
},
keySize: 64/32,
ivSize: 64/32,
blockSize: 64/32
});
// Swap bits across the left and right words
function exchangeLR(offset, mask) {
var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask;
this._rBlock ^= t;
this._lBlock ^= t << offset;
}
function exchangeRL(offset, mask) {
var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask;
this._lBlock ^= t;
this._rBlock ^= t << offset;
}
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.DES.encrypt(message, key, cfg);
* var plaintext = CryptoJS.DES.decrypt(ciphertext, key, cfg);
*/
C.DES = BlockCipher._createHelper(DES);
/**
* Triple-DES block cipher algorithm.
*/
var TripleDES = C_algo.TripleDES = BlockCipher.extend({
_doReset: function () {
// Shortcuts
var key = this._key;
var keyWords = key.words;
// Make sure the key length is valid (64, 128 or >= 192 bit)
if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) {
throw new Error('Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.');
}
// Extend the key according to the keying options defined in 3DES standard
var key1 = keyWords.slice(0, 2);
var key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4);
var key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6);
// Create DES instances
this._des1 = DES.createEncryptor(WordArray.create(key1));
this._des2 = DES.createEncryptor(WordArray.create(key2));
this._des3 = DES.createEncryptor(WordArray.create(key3));
},
encryptBlock: function (M, offset) {
this._des1.encryptBlock(M, offset);
this._des2.decryptBlock(M, offset);
this._des3.encryptBlock(M, offset);
},
decryptBlock: function (M, offset) {
this._des3.decryptBlock(M, offset);
this._des2.encryptBlock(M, offset);
this._des1.decryptBlock(M, offset);
},
keySize: 192/32,
ivSize: 64/32,
blockSize: 64/32
});
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg);
* var plaintext = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg);
*/
C.TripleDES = BlockCipher._createHelper(TripleDES);
}());
return CryptoJS.TripleDES;
}));

View File

@@ -0,0 +1,304 @@
;(function (root, factory) {
if (typeof exports === "object") {
// CommonJS
module.exports = exports = factory(require("./core"));
}
else if (typeof define === "function" && define.amd) {
// AMD
define(["./core"], factory);
}
else {
// Global (browser)
factory(root.CryptoJS);
}
}(this, function (CryptoJS) {
(function (undefined) {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var Base = C_lib.Base;
var X32WordArray = C_lib.WordArray;
/**
* x64 namespace.
*/
var C_x64 = C.x64 = {};
/**
* A 64-bit word.
*/
var X64Word = C_x64.Word = Base.extend({
/**
* Initializes a newly created 64-bit word.
*
* @param {number} high The high 32 bits.
* @param {number} low The low 32 bits.
*
* @example
*
* var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607);
*/
init: function (high, low) {
this.high = high;
this.low = low;
}
/**
* Bitwise NOTs this word.
*
* @return {X64Word} A new x64-Word object after negating.
*
* @example
*
* var negated = x64Word.not();
*/
// not: function () {
// var high = ~this.high;
// var low = ~this.low;
// return X64Word.create(high, low);
// },
/**
* Bitwise ANDs this word with the passed word.
*
* @param {X64Word} word The x64-Word to AND with this word.
*
* @return {X64Word} A new x64-Word object after ANDing.
*
* @example
*
* var anded = x64Word.and(anotherX64Word);
*/
// and: function (word) {
// var high = this.high & word.high;
// var low = this.low & word.low;
// return X64Word.create(high, low);
// },
/**
* Bitwise ORs this word with the passed word.
*
* @param {X64Word} word The x64-Word to OR with this word.
*
* @return {X64Word} A new x64-Word object after ORing.
*
* @example
*
* var ored = x64Word.or(anotherX64Word);
*/
// or: function (word) {
// var high = this.high | word.high;
// var low = this.low | word.low;
// return X64Word.create(high, low);
// },
/**
* Bitwise XORs this word with the passed word.
*
* @param {X64Word} word The x64-Word to XOR with this word.
*
* @return {X64Word} A new x64-Word object after XORing.
*
* @example
*
* var xored = x64Word.xor(anotherX64Word);
*/
// xor: function (word) {
// var high = this.high ^ word.high;
// var low = this.low ^ word.low;
// return X64Word.create(high, low);
// },
/**
* Shifts this word n bits to the left.
*
* @param {number} n The number of bits to shift.
*
* @return {X64Word} A new x64-Word object after shifting.
*
* @example
*
* var shifted = x64Word.shiftL(25);
*/
// shiftL: function (n) {
// if (n < 32) {
// var high = (this.high << n) | (this.low >>> (32 - n));
// var low = this.low << n;
// } else {
// var high = this.low << (n - 32);
// var low = 0;
// }
// return X64Word.create(high, low);
// },
/**
* Shifts this word n bits to the right.
*
* @param {number} n The number of bits to shift.
*
* @return {X64Word} A new x64-Word object after shifting.
*
* @example
*
* var shifted = x64Word.shiftR(7);
*/
// shiftR: function (n) {
// if (n < 32) {
// var low = (this.low >>> n) | (this.high << (32 - n));
// var high = this.high >>> n;
// } else {
// var low = this.high >>> (n - 32);
// var high = 0;
// }
// return X64Word.create(high, low);
// },
/**
* Rotates this word n bits to the left.
*
* @param {number} n The number of bits to rotate.
*
* @return {X64Word} A new x64-Word object after rotating.
*
* @example
*
* var rotated = x64Word.rotL(25);
*/
// rotL: function (n) {
// return this.shiftL(n).or(this.shiftR(64 - n));
// },
/**
* Rotates this word n bits to the right.
*
* @param {number} n The number of bits to rotate.
*
* @return {X64Word} A new x64-Word object after rotating.
*
* @example
*
* var rotated = x64Word.rotR(7);
*/
// rotR: function (n) {
// return this.shiftR(n).or(this.shiftL(64 - n));
// },
/**
* Adds this word with the passed word.
*
* @param {X64Word} word The x64-Word to add with this word.
*
* @return {X64Word} A new x64-Word object after adding.
*
* @example
*
* var added = x64Word.add(anotherX64Word);
*/
// add: function (word) {
// var low = (this.low + word.low) | 0;
// var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0;
// var high = (this.high + word.high + carry) | 0;
// return X64Word.create(high, low);
// }
});
/**
* An array of 64-bit words.
*
* @property {Array} words The array of CryptoJS.x64.Word objects.
* @property {number} sigBytes The number of significant bytes in this word array.
*/
var X64WordArray = C_x64.WordArray = Base.extend({
/**
* Initializes a newly created word array.
*
* @param {Array} words (Optional) An array of CryptoJS.x64.Word objects.
* @param {number} sigBytes (Optional) The number of significant bytes in the words.
*
* @example
*
* var wordArray = CryptoJS.x64.WordArray.create();
*
* var wordArray = CryptoJS.x64.WordArray.create([
* CryptoJS.x64.Word.create(0x00010203, 0x04050607),
* CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
* ]);
*
* var wordArray = CryptoJS.x64.WordArray.create([
* CryptoJS.x64.Word.create(0x00010203, 0x04050607),
* CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
* ], 10);
*/
init: function (words, sigBytes) {
words = this.words = words || [];
if (sigBytes != undefined) {
this.sigBytes = sigBytes;
} else {
this.sigBytes = words.length * 8;
}
},
/**
* Converts this 64-bit word array to a 32-bit word array.
*
* @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array.
*
* @example
*
* var x32WordArray = x64WordArray.toX32();
*/
toX32: function () {
// Shortcuts
var x64Words = this.words;
var x64WordsLength = x64Words.length;
// Convert
var x32Words = [];
for (var i = 0; i < x64WordsLength; i++) {
var x64Word = x64Words[i];
x32Words.push(x64Word.high);
x32Words.push(x64Word.low);
}
return X32WordArray.create(x32Words, this.sigBytes);
},
/**
* Creates a copy of this word array.
*
* @return {X64WordArray} The clone.
*
* @example
*
* var clone = x64WordArray.clone();
*/
clone: function () {
var clone = Base.clone.call(this);
// Clone "words" array
var words = clone.words = this.words.slice(0);
// Clone each X64Word object
var wordsLength = words.length;
for (var i = 0; i < wordsLength; i++) {
words[i] = words[i].clone();
}
return clone;
}
});
}());
return CryptoJS;
}));

159
nx/utils/crypto.js Normal file
View File

@@ -0,0 +1,159 @@
import CryptoJS from 'crypto-js';
import { SM4 } from 'gm-crypto';
import { apiCrypto } from '@/nx/config'
/**
* api报文加密
*/
export class ApiEncryption {
constructor() {
this.defaultEncType = apiCrypto.type
this.aesKey = apiCrypto.aesKey
this.desKey = apiCrypto.desKey
this.sm4Key = apiCrypto.sm4Key
}
/**
* 加密数据
* @param data 待加密的数据
* @returns
*/
encrypt(data) {
let encryptData
switch (this.defaultEncType) {
case 'aes':
encryptData = this.encryptAES(data, this.aesKey)
break
case 'des':
encryptData = this.encryptDES(data, this.desKey)
break
case 'sm4':
encryptData = this.encryptSM4(data, this.sm4Key)
break
default:
encryptData = this.encryptAES(data, this.aesKey)
break
}
return encryptData
}
/**
* 解密
* @param data 待解密的数据
* @returns
*/
decrypt(data) {
let decryptData
switch (this.defaultEncType) {
case 'aes':
decryptData = this.decryptAES(data, this.aesKey)
break
case 'des':
decryptData = this.decryptDES(data, this.desKey)
break
case 'sm4':
decryptData = this.decryptSM4(data, this.sm4Key)
break
default:
decryptData = this.decryptAES(data, this.aesKey)
break
}
return decryptData
}
/**
* aes加密
* @param data 待加密数据
* @param key aes密钥
* @returns
*/
encryptAES(data, key) {
const dataBytes = CryptoJS.enc.Utf8.parse(data)
const keyBytes = CryptoJS.enc.Utf8.parse(key)
const encrypted = CryptoJS.AES.encrypt(dataBytes, keyBytes, {
iv: keyBytes,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return CryptoJS.enc.Base64.stringify(encrypted.ciphertext)
}
/**
* aes解密
* @param data 待解密数据
* @param key 密钥key
* @returns
*/
decryptAES(data, key) {
const keyBytes = CryptoJS.enc.Utf8.parse(key)
const decrypted = CryptoJS.AES.decrypt(data, keyBytes, {
iv: keyBytes,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return CryptoJS.enc.Utf8.stringify(decrypted)
}
/**
* des加密
* @param data 待加密数据
* @param key des密钥
* @returns
*/
encryptDES(data, key) {
const keyBytes = CryptoJS.enc.Utf8.parse(key)
const encrypted = CryptoJS.DES.encrypt(data, keyBytes, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return encrypted.toString()
}
/**
* des解密
* @param data 待解密数据
* @param key des密钥
* @returns
*/
decryptDES(data, key) {
const keyBytes = CryptoJS.enc.Utf8.parse(key)
//const cipherText = CryptoJS.enc.Base64.parse(data);
const decrypted = CryptoJS.DES.decrypt(data, keyBytes, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8)
}
/**
* sm4加密
* @param data 待加密数据
* @param key sm4密钥
*/
encryptSM4(data, key) {
const keyBytes = CryptoJS.enc.Utf8.parse(key)
const keyHex = CryptoJS.enc.Hex.stringify(keyBytes)
//console.log(data);
//console.log(keyHex);
return SM4.encrypt(data, keyHex, {
inputEncoding: 'utf8',
outputEncoding: 'base64'
})
}
/**
* sm4解密
* @param data 待解密数据
* @param key sm4密钥
*/
decryptSM4(data, key) {
const keyBytes = CryptoJS.enc.Utf8.parse(key)
const keyHex = CryptoJS.enc.Hex.stringify(keyBytes)
return SM4.decrypt(data, keyHex, {
inputEncoding: 'base64',
outputEncoding: 'utf8'
})
}
}

View File

@@ -0,0 +1,3 @@
export * as SM2 from './lib/sm2/'
export * as SM3 from './lib/sm3'
export * as SM4 from './lib/sm4'

View File

@@ -0,0 +1,3 @@
export const C1C2C3 = 0
export const C1C3C2 = 1
export const PC = '04' // 未压缩

View File

@@ -0,0 +1,415 @@
// Basic Javascript Elliptic Curve implementation
// Ported loosely from BouncyCastle's Java EC code
// Only Fp curves implemented for now
// Requires jsbn.js and jsbn2.js
import { BigInteger } from 'jsbn'
const { Barrett } = BigInteger.prototype
// Basic Javascript Elliptic Curve implementation
// Ported loosely from BouncyCastle's Java EC code
// Only Fp curves implemented for now
// Requires jsbn.js and jsbn2.js
// ----------------
// ECFieldElementFp
// constructor
function ECFieldElementFp(q, x) {
this.x = x
// TODO if(x.compareTo(q) >= 0) error
this.q = q
}
function feFpEquals(other) {
if (other == this) return true
return this.q.equals(other.q) && this.x.equals(other.x)
}
function feFpToBigInteger() {
return this.x
}
function feFpNegate() {
return new ECFieldElementFp(this.q, this.x.negate().mod(this.q))
}
function feFpAdd(b) {
return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q))
}
function feFpSubtract(b) {
return new ECFieldElementFp(
this.q,
this.x.subtract(b.toBigInteger()).mod(this.q)
)
}
function feFpMultiply(b) {
return new ECFieldElementFp(
this.q,
this.x.multiply(b.toBigInteger()).mod(this.q)
)
}
function feFpSquare() {
return new ECFieldElementFp(this.q, this.x.square().mod(this.q))
}
function feFpDivide(b) {
return new ECFieldElementFp(
this.q,
this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)
)
}
ECFieldElementFp.prototype.equals = feFpEquals
ECFieldElementFp.prototype.toBigInteger = feFpToBigInteger
ECFieldElementFp.prototype.negate = feFpNegate
ECFieldElementFp.prototype.add = feFpAdd
ECFieldElementFp.prototype.subtract = feFpSubtract
ECFieldElementFp.prototype.multiply = feFpMultiply
ECFieldElementFp.prototype.square = feFpSquare
ECFieldElementFp.prototype.divide = feFpDivide
// ----------------
// ECPointFp
// constructor
export function ECPointFp(curve, x, y, z) {
this.curve = curve
this.x = x
this.y = y
// Projective coordinates: either zinv == null or z * zinv == 1
// z and zinv are just BigIntegers, not fieldElements
if (z == null) {
this.z = BigInteger.ONE
} else {
this.z = z
}
this.zinv = null
//TODO: compression flag
}
function pointFpGetX() {
if (this.zinv == null) {
this.zinv = this.z.modInverse(this.curve.q)
}
var r = this.x.toBigInteger().multiply(this.zinv)
this.curve.reduce(r)
return this.curve.fromBigInteger(r)
}
function pointFpGetY() {
if (this.zinv == null) {
this.zinv = this.z.modInverse(this.curve.q)
}
var r = this.y.toBigInteger().multiply(this.zinv)
this.curve.reduce(r)
return this.curve.fromBigInteger(r)
}
function pointFpEquals(other) {
if (other == this) return true
if (this.isInfinity()) return other.isInfinity()
if (other.isInfinity()) return this.isInfinity()
var u, v
// u = Y2 * Z1 - Y1 * Z2
u = other.y
.toBigInteger()
.multiply(this.z)
.subtract(this.y.toBigInteger().multiply(other.z))
.mod(this.curve.q)
if (!u.equals(BigInteger.ZERO)) return false
// v = X2 * Z1 - X1 * Z2
v = other.x
.toBigInteger()
.multiply(this.z)
.subtract(this.x.toBigInteger().multiply(other.z))
.mod(this.curve.q)
return v.equals(BigInteger.ZERO)
}
function pointFpIsInfinity() {
if (this.x == null && this.y == null) return true
return (
this.z.equals(BigInteger.ZERO) &&
!this.y.toBigInteger().equals(BigInteger.ZERO)
)
}
function pointFpNegate() {
return new ECPointFp(this.curve, this.x, this.y.negate(), this.z)
}
function pointFpAdd(b) {
if (this.isInfinity()) return b
if (b.isInfinity()) return this
// u = Y2 * Z1 - Y1 * Z2
var u = b.y
.toBigInteger()
.multiply(this.z)
.subtract(this.y.toBigInteger().multiply(b.z))
.mod(this.curve.q)
// v = X2 * Z1 - X1 * Z2
var v = b.x
.toBigInteger()
.multiply(this.z)
.subtract(this.x.toBigInteger().multiply(b.z))
.mod(this.curve.q)
if (BigInteger.ZERO.equals(v)) {
if (BigInteger.ZERO.equals(u)) {
return this.twice() // this == b, so double
}
return this.curve.getInfinity() // this = -b, so infinity
}
var THREE = new BigInteger('3')
var x1 = this.x.toBigInteger()
var y1 = this.y.toBigInteger()
var x2 = b.x.toBigInteger()
var y2 = b.y.toBigInteger()
var v2 = v.square()
var v3 = v2.multiply(v)
var x1v2 = x1.multiply(v2)
var zu2 = u.square().multiply(this.z)
// x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3)
var x3 = zu2
.subtract(x1v2.shiftLeft(1))
.multiply(b.z)
.subtract(v3)
.multiply(v)
.mod(this.curve.q)
// y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3
var y3 = x1v2
.multiply(THREE)
.multiply(u)
.subtract(y1.multiply(v3))
.subtract(zu2.multiply(u))
.multiply(b.z)
.add(u.multiply(v3))
.mod(this.curve.q)
// z3 = v^3 * z1 * z2
var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q)
return new ECPointFp(
this.curve,
this.curve.fromBigInteger(x3),
this.curve.fromBigInteger(y3),
z3
)
}
function pointFpTwice() {
if (this.isInfinity()) return this
if (this.y.toBigInteger().signum() == 0) return this.curve.getInfinity()
// TODO: optimized handling of constants
var THREE = new BigInteger('3')
var x1 = this.x.toBigInteger()
var y1 = this.y.toBigInteger()
var y1z1 = y1.multiply(this.z)
var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q)
var a = this.curve.a.toBigInteger()
// w = 3 * x1^2 + a * z1^2
var w = x1.square().multiply(THREE)
if (!BigInteger.ZERO.equals(a)) {
w = w.add(this.z.square().multiply(a))
}
w = w.mod(this.curve.q)
//this.curve.reduce(w);
// x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1)
var x3 = w
.square()
.subtract(x1.shiftLeft(3).multiply(y1sqz1))
.shiftLeft(1)
.multiply(y1z1)
.mod(this.curve.q)
// y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3
var y3 = w
.multiply(THREE)
.multiply(x1)
.subtract(y1sqz1.shiftLeft(1))
.shiftLeft(2)
.multiply(y1sqz1)
.subtract(w.square().multiply(w))
.mod(this.curve.q)
// z3 = 8 * (y1 * z1)^3
var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q)
return new ECPointFp(
this.curve,
this.curve.fromBigInteger(x3),
this.curve.fromBigInteger(y3),
z3
)
}
// Simple NAF (Non-Adjacent Form) multiplication algorithm
// TODO: modularize the multiplication algorithm
function pointFpMultiply(k) {
if (this.isInfinity()) return this
if (k.signum() == 0) return this.curve.getInfinity()
var e = k
var h = e.multiply(new BigInteger('3'))
var neg = this.negate()
var R = this
var i
for (i = h.bitLength() - 2; i > 0; --i) {
R = R.twice()
var hBit = h.testBit(i)
var eBit = e.testBit(i)
if (hBit != eBit) {
R = R.add(hBit ? this : neg)
}
}
return R
}
// Compute this*j + x*k (simultaneous multiplication)
function pointFpMultiplyTwo(j, x, k) {
var i
if (j.bitLength() > k.bitLength()) i = j.bitLength() - 1
else i = k.bitLength() - 1
var R = this.curve.getInfinity()
var both = this.add(x)
while (i >= 0) {
R = R.twice()
if (j.testBit(i)) {
if (k.testBit(i)) {
R = R.add(both)
} else {
R = R.add(this)
}
} else {
if (k.testBit(i)) {
R = R.add(x)
}
}
--i
}
return R
}
ECPointFp.prototype.getX = pointFpGetX
ECPointFp.prototype.getY = pointFpGetY
ECPointFp.prototype.equals = pointFpEquals
ECPointFp.prototype.isInfinity = pointFpIsInfinity
ECPointFp.prototype.negate = pointFpNegate
ECPointFp.prototype.add = pointFpAdd
ECPointFp.prototype.twice = pointFpTwice
ECPointFp.prototype.multiply = pointFpMultiply
ECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo
// ----------------
// ECCurveFp
// constructor
export function ECCurveFp(q, a, b) {
this.q = q
this.a = this.fromBigInteger(a)
this.b = this.fromBigInteger(b)
this.infinity = new ECPointFp(this, null, null)
this.reducer = new Barrett(this.q)
}
function curveFpGetQ() {
return this.q
}
function curveFpGetA() {
return this.a
}
function curveFpGetB() {
return this.b
}
function curveFpEquals(other) {
if (other == this) return true
return (
this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)
)
}
function curveFpGetInfinity() {
return this.infinity
}
function curveFpFromBigInteger(x) {
return new ECFieldElementFp(this.q, x)
}
function curveReduce(x) {
this.reducer.reduce(x)
}
// for now, work with hex strings because they're easier in JS
function curveFpDecodePointHex(s) {
switch (
parseInt(s.substr(0, 2), 16) // first byte
) {
case 0:
return this.infinity
case 2:
case 3:
// point compression not supported yet
return null
case 4:
case 6:
case 7:
var len = (s.length - 2) / 2
var xHex = s.substr(2, len)
var yHex = s.substr(len + 2, len)
return new ECPointFp(
this,
this.fromBigInteger(new BigInteger(xHex, 16)),
this.fromBigInteger(new BigInteger(yHex, 16))
)
default:
// unsupported
return null
}
}
function curveFpEncodePointHex(p) {
if (p.isInfinity()) return '00'
var xHex = p.getX().toBigInteger().toString(16)
var yHex = p.getY().toBigInteger().toString(16)
var oLen = this.getQ().toString(16).length
if (oLen % 2 != 0) oLen++
while (xHex.length < oLen) {
xHex = '0' + xHex
}
while (yHex.length < oLen) {
yHex = '0' + yHex
}
return '04' + xHex + yHex
}
ECCurveFp.prototype.getQ = curveFpGetQ
ECCurveFp.prototype.getA = curveFpGetA
ECCurveFp.prototype.getB = curveFpGetB
ECCurveFp.prototype.equals = curveFpEquals
ECCurveFp.prototype.getInfinity = curveFpGetInfinity
ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger
ECCurveFp.prototype.reduce = curveReduce
ECCurveFp.prototype.decodePointHex = curveFpDecodePointHex
ECCurveFp.prototype.encodePointHex = curveFpEncodePointHex

View File

@@ -0,0 +1,238 @@
import toArrayBuffer from 'to-arraybuffer'
import { Buffer } from 'buffer' // 兼容浏览器环境
import { BigInteger, SecureRandom } from 'jsbn'
import { ECCurveFp } from './ec'
import { C1C2C3, C1C3C2, PC } from './const'
import { leftPad } from '../utils'
import { digest } from '../sm3'
// SM2 相关常量
export const constants = { C1C2C3, C1C3C2, PC }
const rng = new SecureRandom()
const { curve, G, n } = (() => {
// p: 大于 3 的素数
const p = new BigInteger(
'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF',
16
)
// ab: Fq 中的元素,它们定义 Fq 上的一条椭圆曲线 E
const a = new BigInteger(
'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC',
16
)
const b = new BigInteger(
'28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93',
16
)
const curve = new ECCurveFp(p, a, b)
// 椭圆曲线的一个基点,其阶为素数
const gxHex =
'32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7'
const gyHex =
'BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0'
const G = curve.decodePointHex(PC + gxHex + gyHex)
// 基点 G 的阶
const n = new BigInteger(
'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123',
16
)
return { curve, G, n }
})()
/**
* 密钥派生函数
* a) 初始化一个 32 比特构成的计数器 ct=0x00000001
* b) 对 i 从 1 到 ⌈klen/v⌉ 执行
* b.1) 计算 Hai=Hv(Z ∥ ct)
* b.2) ct++
* c) 若 klen/v 是整数,令 Ha!⌈klen/v⌉ = Ha⌈klen/v⌉否则令 Ha!⌈klen/v⌉ 为 Ha⌈klen/v⌉ 最左边的 (klen (v × ⌊klen/v⌋)) 比特
* d) 令K = Ha1||Ha2|| · · · ||Ha⌈klen/v⌉1||Ha!⌈klen/v⌉
*/
function KDF(Z, klen) {
const list = []
const times = Math.ceil(klen / 32)
const mod = klen % 32
for (let i = 1; i <= times; i++) {
const ct = Buffer.allocUnsafe(4)
ct.writeUInt32BE(i)
const hash = digest(Buffer.concat([Z, ct]))
// Fix: 浏览器端 Buffer.concat 实现有问题,处理不了 list 总长度超过 klen 的情况
list.push(
i === times && mod ? Buffer.from(hash).slice(0, mod) : Buffer.from(hash)
)
}
return Buffer.concat(list, klen)
}
/**
* 生成密钥对
* a) 用随机数发生器产生整数 d ∈ [1,n2]
* b) G 为基点,计算点 P = (xP,yP) = [d]G
* c) 密钥对是 (d,P),其中 d 为私钥P 为公钥
*/
export const generateKeyPair = () => {
// a) 用随机数发生器产生整数 d ∈ [1,n2]
const d = new BigInteger(n.bitLength(), rng)
.mod(n.subtract(new BigInteger('2')))
.add(BigInteger.ONE)
const privateKey = leftPad(d.toString(16), 64)
// b) G 为基点,计算点 P = (xP,yP) = [d]G
const P = G.multiply(d)
const Px = leftPad(P.getX().toBigInteger().toString(16), 64)
const Py = leftPad(P.getY().toBigInteger().toString(16), 64)
const publicKey = PC + Px + Py
// 密钥对是 (d,P),其中 d 为私钥P 为公钥
return { privateKey, publicKey }
}
/**
* 设需要发送的消息为比特串 Mklen 为 M 的比特长度。
* 为了对明文 M 进行加密,作为加密者的用户 A 应实现以下运算步骤:
* A1用随机数发生器产生随机数 k∈[1,n-1]
* A2计算椭圆曲线点 C1=[k]G=(x1,y1)
* A3计算椭圆曲线点 S=[h]PB若 S 是无穷远点,则报错并退出
* A4计算椭圆曲线点 [k]PB=(x2,y2)
* A5计算 t=KDF(x2 ∥ y2, klen),若 t 为全 0 比特串,则返回 A1
* A6计算 C2 = M ⊕ t
* A7计算 C3 = Hash(x2 ∥ M ∥ y2)
* A8输出密文 C = C1 ∥ C2 ∥ C3 or C1 ∥ C3 ∥ C2
*
* @param {string|Buffer|ArrayBuffer} data
* @param {string} publicKey
*/
export function encrypt(data, publicKey, options) {
const { mode = C1C3C2, inputEncoding, outputEncoding, pc } = options || {}
// 明文消息类型校验 `string` | `ArrayBuffer` | `Buffer`
if (typeof data === 'string') {
data = Buffer.from(data, inputEncoding || 'utf8')
} else if (data instanceof ArrayBuffer) {
data = Buffer.from(data)
}
if (!Buffer.isBuffer(data)) {
throw new TypeError(
`Expected "string" | "Buffer" | "ArrayBuffer" but received "${Object.prototype.toString.call(
data
)}"`
)
}
// 随机数 k∈[1,n-1]
const k = new BigInteger(n.bitLength(), rng)
.mod(n.subtract(BigInteger.ONE))
.add(BigInteger.ONE)
// C1 = [k]G = (x1,y1)
const point1 = G.multiply(k)
const x1 = leftPad(point1.getX().toBigInteger().toString(16), 64)
const y1 = leftPad(point1.getY().toBigInteger().toString(16), 64)
const C1 = x1 + y1
// TODO: 计算椭圆曲线点 S=[h]PB若 S 是无穷远点,则报错并退出
// [k]PB = (x2,y2)
const point2 = curve.decodePointHex(publicKey).multiply(k)
const x2 = leftPad(point2.getX().toBigInteger().toString(16), 64)
const y2 = leftPad(point2.getY().toBigInteger().toString(16), 64)
// t = KDF(x2 ∥ y2, klen),若 t 为全 0 比特串,则返回 A1
const t = KDF(Buffer.from(x2 + y2, 'hex'), data.length)
// C2 = M ⊕ t
const C2 = leftPad(
new BigInteger(data.toString('hex'), 16)
.xor(new BigInteger(t.toString('hex'), 16))
.toString(16),
data.length * 2
)
// C3 = Hash(x2 ∥ M ∥ y2)
const C3 = digest(x2 + data.toString('hex') + y2, 'hex', 'hex')
const buff = Buffer.from((pc ? '04' : '') + (mode === C1C2C3 ? C1 + C2 + C3 : C1 + C3 + C2), 'hex')
return outputEncoding ? buff.toString(outputEncoding) : toArrayBuffer(buff)
}
/**
* 设 klen 为密文中 C2 的比特长度
* 为了对密文 C= C1 ∥ C2 ∥ C3 进行解密作为解密者的用户B应实现以下运算步骤
* B1从 C 中取出比特串 C1转换为椭圆曲线上的点
* B2计算椭圆曲线点 S=[h]C1若 S 是无穷远点,则报错并退出;
* B3计算 [dB]C1=(x2,y2),将坐标 x2、y2 的数据类型转换为比特串;
* B4计算 t=KDF(x2 ∥ y2, klen),若 t 为全 0 比特串,则报错并退出;
* B5从 C 中取出比特串 C2计算 M = C2 ⊕ t
* B6计算 u = Hash(x2 ∥ M ∥ y2),从 C 中取出比特串 C3若u ̸= C3则报错并退出
* B7输出明文M
*
* @param {string|Buffer|ArrayBuffer} data
* @param {string} publicKey
*/
export function decrypt(data, privateKey, options) {
const { mode = C1C3C2, inputEncoding, outputEncoding, pc } = options || {}
// 密文数据类型校验 `string` | `ArrayBuffer` | `Buffer`
if (typeof data === 'string') {
data = Buffer.from(data, inputEncoding)
} else if (data instanceof ArrayBuffer) {
data = Buffer.from(data)
}
if (!Buffer.isBuffer(data)) {
throw new TypeError(
`Expected "string" | "Buffer" | "ArrayBuffer" but received "${Object.prototype.toString.call(
data
)}"`
)
}
data = pc ? data.slice(1) : data
const unit = 32
// 从 C 中取出比特串 C1转换为椭圆曲线上的点
const x1 = data.slice(0, unit).toString('hex')
const y1 = data.slice(unit, 2 * unit).toString('hex')
const point1 = curve.decodePointHex(PC + x1 + y1)
// TODO: 计算椭圆曲线点 S=[h]C1若 S 是无穷远点,则报错并退出;
// [dB]C1 = (x2,y2)
const point2 = point1.multiply(new BigInteger(privateKey, 16))
const x2 = leftPad(point2.getX().toBigInteger().toString(16), 64)
const y2 = leftPad(point2.getY().toBigInteger().toString(16), 64)
// 根据拼接模式拆分数据 C2, C3
let C3 = data.slice(2 * unit, 3 * unit)
let C2 = data.slice(3 * unit)
if (mode === C1C2C3) {
C3 = data.slice(data.length - unit)
C2 = data.slice(2 * unit, data.length - unit)
}
// t = KDF(x2 ∥ y2, klen),若 t 为全 0 比特串,则返回 A1
const t = KDF(Buffer.from(x2 + y2, 'hex'), C2.length)
// M = C2 ⊕ t
const M = new BigInteger(C2.toString('hex'), 16)
.xor(new BigInteger(t.toString('hex'), 16))
.toString(16)
// 计算 u = Hash(x2 ∥ M ∥ y2)
const u = digest(x2 + M + y2, 'hex', 'hex')
// 合法性校验
const verified = u === C3.toString('hex')
const buff = verified ? Buffer.from(M, 'hex') : Buffer.alloc(0)
return outputEncoding ? buff.toString(outputEncoding) : toArrayBuffer(buff)
}

View File

@@ -0,0 +1,147 @@
import toArrayBuffer from 'to-arraybuffer'
import { Buffer } from 'buffer' // 兼容浏览器环境
import { leftShift } from './utils'
// 官方文档以比特作为操作单位,此处以字节作为操作单位。
const padding = (buf) => {
// 首字节 0b10000000 填充
const p1 = Buffer.alloc(1, 0x80)
// 取值 "0" 的 k 比特填充
let k = buf.length % 64 // 64 * 8 === 512
k = k >= 56 ? 64 - (k % 56) - 1 : 56 - k - 1 // 56 * 8 === 448
const p2 = Buffer.alloc(k, 0)
// 64 比特(8 字节)的消息长度填充
const p3 = Buffer.alloc(8)
const size = buf.length * 8 // 不超过 2^53 -1
p3.writeUInt32BE(Math.floor(size / 2 ** 32), 0) // 高 32 位
p3.writeUInt32BE(size % 2 ** 32, 4) // 低 32 位
return Buffer.concat([buf, p1, p2, p3], buf.length + 1 + k + 8)
}
const T = (j) => (j < 16 ? 0x79cc4519 : 0x7a879d8a)
const FF = (X, Y, Z, j) => (j < 16 ? X ^ Y ^ Z : (X & Y) | (X & Z) | (Y & Z))
const GG = (X, Y, Z, j) => (j < 16 ? X ^ Y ^ Z : (X & Y) | (~X & Z))
const P0 = (X) => X ^ leftShift(X, 9) ^ leftShift(X, 17)
const P1 = (X) => X ^ leftShift(X, 15) ^ leftShift(X, 23)
// 消息扩展(512-bits): 16 个字 => 132 个字
const extendFn = (Bi) => {
const W = new Array(132)
// 将消息分组 B(i) 划分为 16 个字 W0, W1, · · · , W15
Bi.forEach((v, i) => {
W[i] = v
})
/**
FOR j=16 TO 67
Wj ← P1(Wj16 ⊕ Wj9 ⊕ (Wj3 ≪ 15)) ⊕ (Wj13 ≪ 7) ⊕ Wj6
ENDFOR
*/
for (let j = 16; j < 68; j++) {
W[j] =
P1(W[j - 16] ^ W[j - 9] ^ leftShift(W[j - 3], 15)) ^
leftShift(W[j - 13], 7) ^
W[j - 6]
}
/**
FOR j=0 TO 63
Wj = Wj ⊕ Wj+4
ENDFOR
*/
for (let j = 0; j < 64; j++) {
W[j + 68] = W[j] ^ W[j + 4]
}
return W
}
// 压缩函数
// - Vi => 8 个字(256-bits)
// - Bi => 16 个字(512-bits)
const CF = (Vi, Bi, i) => {
const W = extendFn(Bi) // 消息扩展, 返回 132 个字
let [A, B, C, D, E, F, G, H] = Vi
let SS1, SS2, TT1, TT2
for (let j = 0; j < 64; j++) {
SS1 = leftShift(leftShift(A, 12) + E + leftShift(T(j), j), 7)
SS2 = SS1 ^ leftShift(A, 12)
TT1 = FF(A, B, C, j) + D + SS2 + W[j + 68]
TT2 = GG(E, F, G, j) + H + SS1 + W[j]
D = C
C = leftShift(B, 9)
B = A
A = TT1
H = G
G = leftShift(F, 19)
F = E
E = P0(TT2)
}
return [
A ^ Vi[0],
B ^ Vi[1],
C ^ Vi[2],
D ^ Vi[3],
E ^ Vi[4],
F ^ Vi[5],
G ^ Vi[6],
H ^ Vi[7]
]
}
export const digest = (data, inputEncoding, outputEncoding) => {
// 输入参数校验 `string` | `ArrayBuffer` | `Buffer`
if (typeof data === 'string') {
data = Buffer.from(data, inputEncoding || 'utf8')
} else if (data instanceof ArrayBuffer) {
data = Buffer.from(data)
}
if (!Buffer.isBuffer(data)) {
throw new TypeError(
`Expected "string" | "Buffer" | "ArrayBuffer" but received "${Object.prototype.toString.call(
data
)}"`
)
}
data = padding(data) // 数据填充
const n = data.length / 64 // 512 比特对应 64 字节
const B = new Array(n)
for (let i = 0; i < n; i++) {
B[i] = new Array(16)
for (let j = 0; j < 16; j++) {
const offset = i * 64 + j * 4
B[i][j] = data.readUInt32BE(offset)
}
}
const V = new Array(n)
V[0] = [
0x7380166f,
0x4914b2b9,
0x172442d7,
0xda8a0600,
0xa96f30bc,
0x163138aa,
0xe38dee4d,
0xb0fb0e4e
]
// 迭代压缩
for (let i = 0; i < n; i++) {
V[i + 1] = CF(V[i], B[i], i)
}
const hash = Buffer.alloc(32)
V[n].forEach((i32, j) => hash.writeInt32BE(i32, j * 4))
return outputEncoding ? hash.toString(outputEncoding) : toArrayBuffer(hash)
}

View File

@@ -0,0 +1,604 @@
import toArrayBuffer from 'to-arraybuffer'
import { Buffer } from 'buffer' // 兼容浏览器环境
import { leftShift } from './utils'
// 两种分组模式
const ECB = 1
const CBC = 2
// SM4 相关常量
export const constants = { ECB, CBC }
// S 盒(非线性变换)
const SBOX_TABLE = [
[
0xd6,
0x90,
0xe9,
0xfe,
0xcc,
0xe1,
0x3d,
0xb7,
0x16,
0xb6,
0x14,
0xc2,
0x28,
0xfb,
0x2c,
0x05
],
[
0x2b,
0x67,
0x9a,
0x76,
0x2a,
0xbe,
0x04,
0xc3,
0xaa,
0x44,
0x13,
0x26,
0x49,
0x86,
0x06,
0x99
],
[
0x9c,
0x42,
0x50,
0xf4,
0x91,
0xef,
0x98,
0x7a,
0x33,
0x54,
0x0b,
0x43,
0xed,
0xcf,
0xac,
0x62
],
[
0xe4,
0xb3,
0x1c,
0xa9,
0xc9,
0x08,
0xe8,
0x95,
0x80,
0xdf,
0x94,
0xfa,
0x75,
0x8f,
0x3f,
0xa6
],
[
0x47,
0x07,
0xa7,
0xfc,
0xf3,
0x73,
0x17,
0xba,
0x83,
0x59,
0x3c,
0x19,
0xe6,
0x85,
0x4f,
0xa8
],
[
0x68,
0x6b,
0x81,
0xb2,
0x71,
0x64,
0xda,
0x8b,
0xf8,
0xeb,
0x0f,
0x4b,
0x70,
0x56,
0x9d,
0x35
],
[
0x1e,
0x24,
0x0e,
0x5e,
0x63,
0x58,
0xd1,
0xa2,
0x25,
0x22,
0x7c,
0x3b,
0x01,
0x21,
0x78,
0x87
],
[
0xd4,
0x00,
0x46,
0x57,
0x9f,
0xd3,
0x27,
0x52,
0x4c,
0x36,
0x02,
0xe7,
0xa0,
0xc4,
0xc8,
0x9e
],
[
0xea,
0xbf,
0x8a,
0xd2,
0x40,
0xc7,
0x38,
0xb5,
0xa3,
0xf7,
0xf2,
0xce,
0xf9,
0x61,
0x15,
0xa1
],
[
0xe0,
0xae,
0x5d,
0xa4,
0x9b,
0x34,
0x1a,
0x55,
0xad,
0x93,
0x32,
0x30,
0xf5,
0x8c,
0xb1,
0xe3
],
[
0x1d,
0xf6,
0xe2,
0x2e,
0x82,
0x66,
0xca,
0x60,
0xc0,
0x29,
0x23,
0xab,
0x0d,
0x53,
0x4e,
0x6f
],
[
0xd5,
0xdb,
0x37,
0x45,
0xde,
0xfd,
0x8e,
0x2f,
0x03,
0xff,
0x6a,
0x72,
0x6d,
0x6c,
0x5b,
0x51
],
[
0x8d,
0x1b,
0xaf,
0x92,
0xbb,
0xdd,
0xbc,
0x7f,
0x11,
0xd9,
0x5c,
0x41,
0x1f,
0x10,
0x5a,
0xd8
],
[
0x0a,
0xc1,
0x31,
0x88,
0xa5,
0xcd,
0x7b,
0xbd,
0x2d,
0x74,
0xd0,
0x12,
0xb8,
0xe5,
0xb4,
0xb0
],
[
0x89,
0x69,
0x97,
0x4a,
0x0c,
0x96,
0x77,
0x7e,
0x65,
0xb9,
0xf1,
0x09,
0xc5,
0x6e,
0xc6,
0x84
],
[
0x18,
0xf0,
0x7d,
0xec,
0x3a,
0xdc,
0x4d,
0x20,
0x79,
0xee,
0x5f,
0x3e,
0xd7,
0xcb,
0x39,
0x48
]
]
/**
* 密钥扩展算法
* - FK: 系统参数
* - CK: 固定参数
*/
const FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]
const CK = [
0x00070e15,
0x1c232a31,
0x383f464d,
0x545b6269,
0x70777e85,
0x8c939aa1,
0xa8afb6bd,
0xc4cbd2d9,
0xe0e7eef5,
0xfc030a11,
0x181f262d,
0x343b4249,
0x50575e65,
0x6c737a81,
0x888f969d,
0xa4abb2b9,
0xc0c7ced5,
0xdce3eaf1,
0xf8ff060d,
0x141b2229,
0x30373e45,
0x4c535a61,
0x686f767d,
0x848b9299,
0xa0a7aeb5,
0xbcc3cad1,
0xd8dfe6ed,
0xf4fb0209,
0x10171e25,
0x2c333a41,
0x484f565d,
0x646b7279
]
// 分组大小
const BLOCK_SIZE = 16 // 16 bytes
// 十六进制表示的加密密钥和初始化向量 iv
const REG_EXP_KEY = /^[0-9a-f]{32}$/i
// 非线性变换 τ(.)
const Tau = (a) => {
const b1 = SBOX_TABLE[(a & 0xf0000000) >>> 28][(a & 0x0f000000) >>> 24]
const b2 = SBOX_TABLE[(a & 0x00f00000) >>> 20][(a & 0x000f0000) >>> 16]
const b3 = SBOX_TABLE[(a & 0x0000f000) >>> 12][(a & 0x00000f00) >>> 8]
const b4 = SBOX_TABLE[(a & 0x000000f0) >>> 4][(a & 0x0000000f) >>> 0]
return (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0)
}
// 线性变换 L(B) = B xor (B <<< 2) xor (B <<< 10) xor (B <<< 18) xor (B <<< 24)
const L = (B) =>
B ^ leftShift(B, 2) ^ leftShift(B, 10) ^ leftShift(B, 18) ^ leftShift(B, 24)
// 合成置换 T(A) = L(τ(A))
const T = (A) => L(Tau(A))
// 线性变换 L'(B) = B xor (B <<< 13) xor (B <<< 23)
const Li = (B) => B ^ leftShift(B, 13) ^ leftShift(B, 23)
// 合成置换 T'(A) = L'(τ(A))
const Ti = (A) => Li(Tau(A))
// 密钥扩展算法
const extendKeys = (MK) => {
const K = new Array(36)
K[0] = MK[0] ^ FK[0]
K[1] = MK[1] ^ FK[1]
K[2] = MK[2] ^ FK[2]
K[3] = MK[3] ^ FK[3]
const rk = new Array(32)
for (let i = 0; i < 32; i++) {
K[i + 4] = K[i] ^ Ti(K[i + 1] ^ K[i + 2] ^ K[i + 3] ^ CK[i])
rk[i] = K[i + 4]
}
return rk
}
// 分组加密
const encryptBlock = (X, MK) => {
const rk = extendKeys(MK)
for (let i = 0; i < 32; i++) {
X[i + 4] = X[i] ^ T(X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ rk[i])
}
return [X[35], X[34], X[33], X[32]]
}
// 分组解密
const decryptBlock = (X, MK) => {
const rk = extendKeys(MK).reverse()
for (let i = 0; i < 32; i++) {
X[i + 4] = X[i] ^ T(X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ rk[i])
}
return [X[35], X[34], X[33], X[32]]
}
// 分组填充 https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS#5_and_PKCS#7
const pkcs7Padding = (data) => {
const paddingSize = BLOCK_SIZE - (data.length % BLOCK_SIZE)
const paddingBuff = Buffer.alloc(paddingSize, paddingSize)
return Buffer.concat([data, paddingBuff], data.length + paddingSize)
}
// Block Buffer => Int32 Array
const toInt32Array = (block) => [
block.readInt32BE(0),
block.readInt32BE(4),
block.readInt32BE(8),
block.readInt32BE(12)
]
// Int32 Array => Block Buffer
const toCipcherBlock = (array) => {
const block = Buffer.alloc(16)
for (let i = 0; i < 4; i++) {
block.writeInt32BE(array[i], i * 4)
}
return block
}
const _encrypt = (data, key, iv, outputEncoding) => {
// 初始化向量转换
iv && (iv = toInt32Array(iv))
// 密钥转换
key = toInt32Array(key)
// 分组填充
data = pkcs7Padding(data)
// 分组加密结果
const blocks = []
// 分组数(每组 16 字节)
const num = data.length / BLOCK_SIZE
for (let i = 0; i < num; i++) {
if (iv) {
const offset = i * BLOCK_SIZE
const plainBlock = [
iv[0] ^ data.readInt32BE(offset),
iv[1] ^ data.readInt32BE(offset + 4),
iv[2] ^ data.readInt32BE(offset + 8),
iv[3] ^ data.readInt32BE(offset + 12)
]
const cipherBlock = encryptBlock(plainBlock, key)
blocks.push(toCipcherBlock(cipherBlock))
iv = cipherBlock.slice(0) // 将本次密文作为下一次加密的 iv
} else {
const offset = i * BLOCK_SIZE
const plainBlock = [
data.readInt32BE(offset),
data.readInt32BE(offset + 4),
data.readInt32BE(offset + 8),
data.readInt32BE(offset + 12)
]
const cipherBlock = encryptBlock(plainBlock, key)
blocks.push(toCipcherBlock(cipherBlock))
}
}
const buff = Buffer.concat(blocks, data.length)
return outputEncoding ? buff.toString(outputEncoding) : toArrayBuffer(buff)
}
const _decrypt = (data, key, iv, outputEncoding) => {
// 初始化向量转换
iv && (iv = toInt32Array(iv))
// 密钥转换
key = toInt32Array(key)
// 分组解密结果
const blocks = []
// 按每组 16 字节分组后得到的总分组数
const num = data.length / BLOCK_SIZE
if (iv) {
for (let i = num - 1; i >= 0; i--) {
const offset = i * BLOCK_SIZE
let vector
if (i > 0) {
vector = [
data.readInt32BE(offset - BLOCK_SIZE),
data.readInt32BE(offset - BLOCK_SIZE + 4),
data.readInt32BE(offset - BLOCK_SIZE + 8),
data.readInt32BE(offset - BLOCK_SIZE + 12)
]
} else {
vector = iv
}
const cipherBlock = [
data.readInt32BE(offset),
data.readInt32BE(offset + 4),
data.readInt32BE(offset + 8),
data.readInt32BE(offset + 12)
]
const [b0, b1, b2, b3] = decryptBlock(cipherBlock, key)
const plainBlock = [
b0 ^ vector[0],
b1 ^ vector[1],
b2 ^ vector[2],
b3 ^ vector[3]
]
blocks.unshift(toCipcherBlock(plainBlock))
}
} else {
for (let i = 0; i < num; i++) {
const offset = i * BLOCK_SIZE
const cipherBlock = [
data.readInt32BE(offset),
data.readInt32BE(offset + 4),
data.readInt32BE(offset + 8),
data.readInt32BE(offset + 12)
]
const plainBlock = decryptBlock(cipherBlock, key)
blocks.push(toCipcherBlock(plainBlock))
}
}
// 移除分组填充
const buff = Buffer.concat(
blocks,
data.length - blocks[blocks.length - 1][BLOCK_SIZE - 1]
)
return outputEncoding ? buff.toString(outputEncoding) : toArrayBuffer(buff)
}
export const encrypt = (data, key, options) => {
let { mode, iv, inputEncoding, outputEncoding } = options || {}
// 输入参数校验 `string` | `ArrayBuffer` | `Buffer`
if (typeof data === 'string') {
data = Buffer.from(data, inputEncoding || 'utf8')
} else if (data instanceof ArrayBuffer) {
data = Buffer.from(data)
}
if (!Buffer.isBuffer(data)) {
throw new TypeError(
`Expected "string" | "Buffer" | "ArrayBuffer" but received "${Object.prototype.toString.call(
data
)}"`
)
}
// 十六进制表示的密钥
if (!REG_EXP_KEY.test(key)) {
throw new TypeError('Invalid value of cipher `key`')
}
key = Buffer.from(key, 'hex')
// CBC 分组必须制定 iv
if (mode === CBC && !REG_EXP_KEY.test(iv)) {
throw new TypeError('Invalid value of `iv` option')
}
iv = mode === CBC ? Buffer.from(iv, 'hex') : null
return _encrypt(data, key, iv, outputEncoding)
}
export const decrypt = (data, key, options) => {
let { mode, iv, inputEncoding, outputEncoding } = options || {}
// 输入参数校验 `string` | `ArrayBuffer` | `Buffer`
if (typeof data === 'string') {
data = Buffer.from(data, inputEncoding)
} else if (data instanceof ArrayBuffer) {
data = Buffer.from(data)
}
if (!Buffer.isBuffer(data)) {
throw new TypeError(
`Expected "string" | "Buffer" | "ArrayBuffer" but received "${Object.prototype.toString.call(
data
)}"`
)
}
// 十六进制表示的密钥
if (!REG_EXP_KEY.test(key)) {
throw new TypeError('Invalid value of cipher `key`')
}
key = Buffer.from(key, 'hex')
// CBC 分组必须制定 iv
if (mode === CBC && !REG_EXP_KEY.test(iv)) {
throw new TypeError('Invalid value of `iv` option')
}
iv = mode === CBC ? Buffer.from(iv, 'hex') : null
return _decrypt(data, key, iv, outputEncoding)
}

View File

@@ -0,0 +1,11 @@
// 32 位整数无符号循环左移
export const leftShift = (a, n) => {
n = n % 32
return (a << n) | (a >>> (32 - n))
}
// 补全 16 进制字符串
export const leftPad = (str, num) => {
const padding = num - str.length
return (padding > 0 ? '0'.repeat(padding) : '') + str
}

685
nx/utils/md5.js Normal file
View File

@@ -0,0 +1,685 @@
/**
* [js-md5]{@link https://github.com/emn178/js-md5}
*
* @namespace md5
* @version 0.7.3
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2014-2017
* @license MIT
*/
(function () {
'use strict';
var ERROR = 'input is invalid type';
var WINDOW = typeof window === 'object';
var root = WINDOW ? window : {};
if (root.JS_MD5_NO_WINDOW) {
WINDOW = false;
}
var WEB_WORKER = !WINDOW && typeof self === 'object';
var NODE_JS = !root.JS_MD5_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
if (NODE_JS) {
root = global;
} else if (WEB_WORKER) {
root = self;
}
var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && typeof module === 'object' && module.exports;
var AMD = typeof define === 'function' && define.amd;
var ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
var HEX_CHARS = '0123456789abcdef'.split('');
var EXTRA = [128, 32768, 8388608, -2147483648];
var SHIFT = [0, 8, 16, 24];
var OUTPUT_TYPES = ['hex', 'array', 'digest', 'buffer', 'arrayBuffer', 'base64'];
var BASE64_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
var blocks = [], buffer8;
if (ARRAY_BUFFER) {
var buffer = new ArrayBuffer(68);
buffer8 = new Uint8Array(buffer);
blocks = new Uint32Array(buffer);
}
if (root.JS_MD5_NO_NODE_JS || !Array.isArray) {
Array.isArray = function (obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};
}
if (ARRAY_BUFFER && (root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
ArrayBuffer.isView = function (obj) {
return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
};
}
/**
* @method hex
* @memberof md5
* @description Output hash as hex string
* @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
* @returns {String} Hex string
* @example
* md5.hex('The quick brown fox jumps over the lazy dog');
* // equal to
* md5('The quick brown fox jumps over the lazy dog');
*/
/**
* @method digest
* @memberof md5
* @description Output hash as bytes array
* @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
* @returns {Array} Bytes array
* @example
* md5.digest('The quick brown fox jumps over the lazy dog');
*/
/**
* @method array
* @memberof md5
* @description Output hash as bytes array
* @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
* @returns {Array} Bytes array
* @example
* md5.array('The quick brown fox jumps over the lazy dog');
*/
/**
* @method arrayBuffer
* @memberof md5
* @description Output hash as ArrayBuffer
* @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
* @returns {ArrayBuffer} ArrayBuffer
* @example
* md5.arrayBuffer('The quick brown fox jumps over the lazy dog');
*/
/**
* @method buffer
* @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
* @memberof md5
* @description Output hash as ArrayBuffer
* @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
* @returns {ArrayBuffer} ArrayBuffer
* @example
* md5.buffer('The quick brown fox jumps over the lazy dog');
*/
/**
* @method base64
* @memberof md5
* @description Output hash as base64 string
* @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
* @returns {String} base64 string
* @example
* md5.base64('The quick brown fox jumps over the lazy dog');
*/
var createOutputMethod = function (outputType) {
return function (message) {
return new Md5(true).update(message)[outputType]();
};
};
/**
* @method create
* @memberof md5
* @description Create Md5 object
* @returns {Md5} Md5 object.
* @example
* var hash = md5.create();
*/
/**
* @method update
* @memberof md5
* @description Create and update Md5 object
* @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
* @returns {Md5} Md5 object.
* @example
* var hash = md5.update('The quick brown fox jumps over the lazy dog');
* // equal to
* var hash = md5.create();
* hash.update('The quick brown fox jumps over the lazy dog');
*/
var createMethod = function () {
var method = createOutputMethod('hex');
if (NODE_JS) {
method = nodeWrap(method);
}
method.create = function () {
return new Md5();
};
method.update = function (message) {
return method.create().update(message);
};
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createOutputMethod(type);
}
return method;
};
var nodeWrap = function (method) {
var crypto = eval("require('crypto')");
var Buffer = eval("require('buffer').Buffer");
var nodeMethod = function (message) {
if (typeof message === 'string') {
return crypto.createHash('md5').update(message, 'utf8').digest('hex');
} else {
if (message === null || message === undefined) {
throw ERROR;
} else if (message.constructor === ArrayBuffer) {
message = new Uint8Array(message);
}
}
if (Array.isArray(message) || ArrayBuffer.isView(message) ||
message.constructor === Buffer) {
return crypto.createHash('md5').update(new Buffer(message)).digest('hex');
} else {
return method(message);
}
};
return nodeMethod;
};
/**
* Md5 class
* @class Md5
* @description This is internal class.
* @see {@link md5.create}
*/
function Md5(sharedMemory) {
if (sharedMemory) {
blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
this.blocks = blocks;
this.buffer8 = buffer8;
} else {
if (ARRAY_BUFFER) {
var buffer = new ArrayBuffer(68);
this.buffer8 = new Uint8Array(buffer);
this.blocks = new Uint32Array(buffer);
} else {
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
}
this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0;
this.finalized = this.hashed = false;
this.first = true;
}
/**
* @method update
* @memberof Md5
* @instance
* @description Update hash
* @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
* @returns {Md5} Md5 object.
* @see {@link md5.update}
*/
Md5.prototype.update = function (message) {
if (this.finalized) {
return;
}
var notString, type = typeof message;
if (type !== 'string') {
if (type === 'object') {
if (message === null) {
throw ERROR;
} else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
message = new Uint8Array(message);
} else if (!Array.isArray(message)) {
if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
throw ERROR;
}
}
} else {
throw ERROR;
}
notString = true;
}
var code, index = 0, i, length = message.length, blocks = this.blocks;
var buffer8 = this.buffer8;
while (index < length) {
if (this.hashed) {
this.hashed = false;
blocks[0] = blocks[16];
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
}
if (notString) {
if (ARRAY_BUFFER) {
for (i = this.start; index < length && i < 64; ++index) {
buffer8[i++] = message[index];
}
} else {
for (i = this.start; index < length && i < 64; ++index) {
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
}
}
} else {
if (ARRAY_BUFFER) {
for (i = this.start; index < length && i < 64; ++index) {
code = message.charCodeAt(index);
if (code < 0x80) {
buffer8[i++] = code;
} else if (code < 0x800) {
buffer8[i++] = 0xc0 | (code >> 6);
buffer8[i++] = 0x80 | (code & 0x3f);
} else if (code < 0xd800 || code >= 0xe000) {
buffer8[i++] = 0xe0 | (code >> 12);
buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);
buffer8[i++] = 0x80 | (code & 0x3f);
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
buffer8[i++] = 0xf0 | (code >> 18);
buffer8[i++] = 0x80 | ((code >> 12) & 0x3f);
buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);
buffer8[i++] = 0x80 | (code & 0x3f);
}
}
} else {
for (i = this.start; index < length && i < 64; ++index) {
code = message.charCodeAt(index);
if (code < 0x80) {
blocks[i >> 2] |= code << SHIFT[i++ & 3];
} else if (code < 0x800) {
blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else if (code < 0xd800 || code >= 0xe000) {
blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
}
}
}
}
this.lastByteIndex = i;
this.bytes += i - this.start;
if (i >= 64) {
this.start = i - 64;
this.hash();
this.hashed = true;
} else {
this.start = i;
}
}
if (this.bytes > 4294967295) {
this.hBytes += this.bytes / 4294967296 << 0;
this.bytes = this.bytes % 4294967296;
}
return this;
};
Md5.prototype.finalize = function () {
if (this.finalized) {
return;
}
this.finalized = true;
var blocks = this.blocks, i = this.lastByteIndex;
blocks[i >> 2] |= EXTRA[i & 3];
if (i >= 56) {
if (!this.hashed) {
this.hash();
}
blocks[0] = blocks[16];
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
}
blocks[14] = this.bytes << 3;
blocks[15] = this.hBytes << 3 | this.bytes >>> 29;
this.hash();
};
Md5.prototype.hash = function () {
var a, b, c, d, bc, da, blocks = this.blocks;
if (this.first) {
a = blocks[0] - 680876937;
a = (a << 7 | a >>> 25) - 271733879 << 0;
d = (-1732584194 ^ a & 2004318071) + blocks[1] - 117830708;
d = (d << 12 | d >>> 20) + a << 0;
c = (-271733879 ^ (d & (a ^ -271733879))) + blocks[2] - 1126478375;
c = (c << 17 | c >>> 15) + d << 0;
b = (a ^ (c & (d ^ a))) + blocks[3] - 1316259209;
b = (b << 22 | b >>> 10) + c << 0;
} else {
a = this.h0;
b = this.h1;
c = this.h2;
d = this.h3;
a += (d ^ (b & (c ^ d))) + blocks[0] - 680876936;
a = (a << 7 | a >>> 25) + b << 0;
d += (c ^ (a & (b ^ c))) + blocks[1] - 389564586;
d = (d << 12 | d >>> 20) + a << 0;
c += (b ^ (d & (a ^ b))) + blocks[2] + 606105819;
c = (c << 17 | c >>> 15) + d << 0;
b += (a ^ (c & (d ^ a))) + blocks[3] - 1044525330;
b = (b << 22 | b >>> 10) + c << 0;
}
a += (d ^ (b & (c ^ d))) + blocks[4] - 176418897;
a = (a << 7 | a >>> 25) + b << 0;
d += (c ^ (a & (b ^ c))) + blocks[5] + 1200080426;
d = (d << 12 | d >>> 20) + a << 0;
c += (b ^ (d & (a ^ b))) + blocks[6] - 1473231341;
c = (c << 17 | c >>> 15) + d << 0;
b += (a ^ (c & (d ^ a))) + blocks[7] - 45705983;
b = (b << 22 | b >>> 10) + c << 0;
a += (d ^ (b & (c ^ d))) + blocks[8] + 1770035416;
a = (a << 7 | a >>> 25) + b << 0;
d += (c ^ (a & (b ^ c))) + blocks[9] - 1958414417;
d = (d << 12 | d >>> 20) + a << 0;
c += (b ^ (d & (a ^ b))) + blocks[10] - 42063;
c = (c << 17 | c >>> 15) + d << 0;
b += (a ^ (c & (d ^ a))) + blocks[11] - 1990404162;
b = (b << 22 | b >>> 10) + c << 0;
a += (d ^ (b & (c ^ d))) + blocks[12] + 1804603682;
a = (a << 7 | a >>> 25) + b << 0;
d += (c ^ (a & (b ^ c))) + blocks[13] - 40341101;
d = (d << 12 | d >>> 20) + a << 0;
c += (b ^ (d & (a ^ b))) + blocks[14] - 1502002290;
c = (c << 17 | c >>> 15) + d << 0;
b += (a ^ (c & (d ^ a))) + blocks[15] + 1236535329;
b = (b << 22 | b >>> 10) + c << 0;
a += (c ^ (d & (b ^ c))) + blocks[1] - 165796510;
a = (a << 5 | a >>> 27) + b << 0;
d += (b ^ (c & (a ^ b))) + blocks[6] - 1069501632;
d = (d << 9 | d >>> 23) + a << 0;
c += (a ^ (b & (d ^ a))) + blocks[11] + 643717713;
c = (c << 14 | c >>> 18) + d << 0;
b += (d ^ (a & (c ^ d))) + blocks[0] - 373897302;
b = (b << 20 | b >>> 12) + c << 0;
a += (c ^ (d & (b ^ c))) + blocks[5] - 701558691;
a = (a << 5 | a >>> 27) + b << 0;
d += (b ^ (c & (a ^ b))) + blocks[10] + 38016083;
d = (d << 9 | d >>> 23) + a << 0;
c += (a ^ (b & (d ^ a))) + blocks[15] - 660478335;
c = (c << 14 | c >>> 18) + d << 0;
b += (d ^ (a & (c ^ d))) + blocks[4] - 405537848;
b = (b << 20 | b >>> 12) + c << 0;
a += (c ^ (d & (b ^ c))) + blocks[9] + 568446438;
a = (a << 5 | a >>> 27) + b << 0;
d += (b ^ (c & (a ^ b))) + blocks[14] - 1019803690;
d = (d << 9 | d >>> 23) + a << 0;
c += (a ^ (b & (d ^ a))) + blocks[3] - 187363961;
c = (c << 14 | c >>> 18) + d << 0;
b += (d ^ (a & (c ^ d))) + blocks[8] + 1163531501;
b = (b << 20 | b >>> 12) + c << 0;
a += (c ^ (d & (b ^ c))) + blocks[13] - 1444681467;
a = (a << 5 | a >>> 27) + b << 0;
d += (b ^ (c & (a ^ b))) + blocks[2] - 51403784;
d = (d << 9 | d >>> 23) + a << 0;
c += (a ^ (b & (d ^ a))) + blocks[7] + 1735328473;
c = (c << 14 | c >>> 18) + d << 0;
b += (d ^ (a & (c ^ d))) + blocks[12] - 1926607734;
b = (b << 20 | b >>> 12) + c << 0;
bc = b ^ c;
a += (bc ^ d) + blocks[5] - 378558;
a = (a << 4 | a >>> 28) + b << 0;
d += (bc ^ a) + blocks[8] - 2022574463;
d = (d << 11 | d >>> 21) + a << 0;
da = d ^ a;
c += (da ^ b) + blocks[11] + 1839030562;
c = (c << 16 | c >>> 16) + d << 0;
b += (da ^ c) + blocks[14] - 35309556;
b = (b << 23 | b >>> 9) + c << 0;
bc = b ^ c;
a += (bc ^ d) + blocks[1] - 1530992060;
a = (a << 4 | a >>> 28) + b << 0;
d += (bc ^ a) + blocks[4] + 1272893353;
d = (d << 11 | d >>> 21) + a << 0;
da = d ^ a;
c += (da ^ b) + blocks[7] - 155497632;
c = (c << 16 | c >>> 16) + d << 0;
b += (da ^ c) + blocks[10] - 1094730640;
b = (b << 23 | b >>> 9) + c << 0;
bc = b ^ c;
a += (bc ^ d) + blocks[13] + 681279174;
a = (a << 4 | a >>> 28) + b << 0;
d += (bc ^ a) + blocks[0] - 358537222;
d = (d << 11 | d >>> 21) + a << 0;
da = d ^ a;
c += (da ^ b) + blocks[3] - 722521979;
c = (c << 16 | c >>> 16) + d << 0;
b += (da ^ c) + blocks[6] + 76029189;
b = (b << 23 | b >>> 9) + c << 0;
bc = b ^ c;
a += (bc ^ d) + blocks[9] - 640364487;
a = (a << 4 | a >>> 28) + b << 0;
d += (bc ^ a) + blocks[12] - 421815835;
d = (d << 11 | d >>> 21) + a << 0;
da = d ^ a;
c += (da ^ b) + blocks[15] + 530742520;
c = (c << 16 | c >>> 16) + d << 0;
b += (da ^ c) + blocks[2] - 995338651;
b = (b << 23 | b >>> 9) + c << 0;
a += (c ^ (b | ~d)) + blocks[0] - 198630844;
a = (a << 6 | a >>> 26) + b << 0;
d += (b ^ (a | ~c)) + blocks[7] + 1126891415;
d = (d << 10 | d >>> 22) + a << 0;
c += (a ^ (d | ~b)) + blocks[14] - 1416354905;
c = (c << 15 | c >>> 17) + d << 0;
b += (d ^ (c | ~a)) + blocks[5] - 57434055;
b = (b << 21 | b >>> 11) + c << 0;
a += (c ^ (b | ~d)) + blocks[12] + 1700485571;
a = (a << 6 | a >>> 26) + b << 0;
d += (b ^ (a | ~c)) + blocks[3] - 1894986606;
d = (d << 10 | d >>> 22) + a << 0;
c += (a ^ (d | ~b)) + blocks[10] - 1051523;
c = (c << 15 | c >>> 17) + d << 0;
b += (d ^ (c | ~a)) + blocks[1] - 2054922799;
b = (b << 21 | b >>> 11) + c << 0;
a += (c ^ (b | ~d)) + blocks[8] + 1873313359;
a = (a << 6 | a >>> 26) + b << 0;
d += (b ^ (a | ~c)) + blocks[15] - 30611744;
d = (d << 10 | d >>> 22) + a << 0;
c += (a ^ (d | ~b)) + blocks[6] - 1560198380;
c = (c << 15 | c >>> 17) + d << 0;
b += (d ^ (c | ~a)) + blocks[13] + 1309151649;
b = (b << 21 | b >>> 11) + c << 0;
a += (c ^ (b | ~d)) + blocks[4] - 145523070;
a = (a << 6 | a >>> 26) + b << 0;
d += (b ^ (a | ~c)) + blocks[11] - 1120210379;
d = (d << 10 | d >>> 22) + a << 0;
c += (a ^ (d | ~b)) + blocks[2] + 718787259;
c = (c << 15 | c >>> 17) + d << 0;
b += (d ^ (c | ~a)) + blocks[9] - 343485551;
b = (b << 21 | b >>> 11) + c << 0;
if (this.first) {
this.h0 = a + 1732584193 << 0;
this.h1 = b - 271733879 << 0;
this.h2 = c - 1732584194 << 0;
this.h3 = d + 271733878 << 0;
this.first = false;
} else {
this.h0 = this.h0 + a << 0;
this.h1 = this.h1 + b << 0;
this.h2 = this.h2 + c << 0;
this.h3 = this.h3 + d << 0;
}
};
/**
* @method hex
* @memberof Md5
* @instance
* @description Output hash as hex string
* @returns {String} Hex string
* @see {@link md5.hex}
* @example
* hash.hex();
*/
Md5.prototype.hex = function () {
this.finalize();
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;
return HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] +
HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] +
HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] +
HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] +
HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] +
HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] +
HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] +
HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] +
HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] +
HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] +
HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] +
HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F];
};
/**
* @method toString
* @memberof Md5
* @instance
* @description Output hash as hex string
* @returns {String} Hex string
* @see {@link md5.hex}
* @example
* hash.toString();
*/
Md5.prototype.toString = Md5.prototype.hex;
/**
* @method digest
* @memberof Md5
* @instance
* @description Output hash as bytes array
* @returns {Array} Bytes array
* @see {@link md5.digest}
* @example
* hash.digest();
*/
Md5.prototype.digest = function () {
this.finalize();
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;
return [
h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 24) & 0xFF,
h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 24) & 0xFF,
h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 24) & 0xFF,
h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 24) & 0xFF
];
};
/**
* @method array
* @memberof Md5
* @instance
* @description Output hash as bytes array
* @returns {Array} Bytes array
* @see {@link md5.array}
* @example
* hash.array();
*/
Md5.prototype.array = Md5.prototype.digest;
/**
* @method arrayBuffer
* @memberof Md5
* @instance
* @description Output hash as ArrayBuffer
* @returns {ArrayBuffer} ArrayBuffer
* @see {@link md5.arrayBuffer}
* @example
* hash.arrayBuffer();
*/
Md5.prototype.arrayBuffer = function () {
this.finalize();
var buffer = new ArrayBuffer(16);
var blocks = new Uint32Array(buffer);
blocks[0] = this.h0;
blocks[1] = this.h1;
blocks[2] = this.h2;
blocks[3] = this.h3;
return buffer;
};
/**
* @method buffer
* @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
* @memberof Md5
* @instance
* @description Output hash as ArrayBuffer
* @returns {ArrayBuffer} ArrayBuffer
* @see {@link md5.buffer}
* @example
* hash.buffer();
*/
Md5.prototype.buffer = Md5.prototype.arrayBuffer;
/**
* @method base64
* @memberof Md5
* @instance
* @description Output hash as base64 string
* @returns {String} base64 string
* @see {@link md5.base64}
* @example
* hash.base64();
*/
Md5.prototype.base64 = function () {
var v1, v2, v3, base64Str = '', bytes = this.array();
for (var i = 0; i < 15;) {
v1 = bytes[i++];
v2 = bytes[i++];
v3 = bytes[i++];
base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +
BASE64_ENCODE_CHAR[(v1 << 4 | v2 >>> 4) & 63] +
BASE64_ENCODE_CHAR[(v2 << 2 | v3 >>> 6) & 63] +
BASE64_ENCODE_CHAR[v3 & 63];
}
v1 = bytes[i];
base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +
BASE64_ENCODE_CHAR[(v1 << 4) & 63] +
'==';
return base64Str;
};
var exports = createMethod();
if (COMMON_JS) {
module.exports = exports;
} else {
/**
* @method md5
* @description Md5 hash function, export to global in browsers.
* @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
* @returns {String} md5 hashes
* @example
* md5(''); // d41d8cd98f00b204e9800998ecf8427e
* md5('The quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6
* md5('The quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0
*
* // It also supports UTF-8 encoding
* md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07
*
* // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer`
* md5([]); // d41d8cd98f00b204e9800998ecf8427e
* md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e
*/
root.md5 = exports;
if (AMD) {
define(function () {
return exports;
});
}
}
})();

121
nx/utils/share.js Normal file
View File

@@ -0,0 +1,121 @@
export default {
data() {
return {
//设置默认的分享参数
shareInfo: {
title: '', //分享标题
path: '', //转发链接 小程序转发只有页面链接和参数,其他全部带域名
imageUrl: '', //分享图片
}
}
},
onLoad(options) {
// options.scene ='FeFy9fhC2TaMMovG5QOdZLeRahzWrayH';
let that = this;
// console.log('nxshare onload options', options);
//为每个页面设置分享信息
that.setShareInfo();
let query = this.$Route.query;
// //直接进入页面
// if (options.page) {
// let page = decodeURIComponent(options.page);
// uni.navigateTo({
// url: page
// })
// }
},
methods: {
setShareInfo(scene = {
title: '', //自定义分享标题
image: '', //自定义分享图片
query: {}, //自定义分享参数
path: '', // 自定义分享路径
}) {
let that = this;
let defaultShareInfo = uni.getStorageSync('shareInfo');
//设置自定义分享标题
if (scene.title != '') {
that.shareInfo.title = scene.title;
} else {
that.shareInfo.title = defaultShareInfo.title;
}
//设置分享图片
if (scene.image != '') {
that.shareInfo.imageUrl = scene.image;
} else {
that.shareInfo.imageUrl = defaultShareInfo.image;
}
//设置分享路径
if (scene.path != '') {
that.shareInfo.path = scene.path;
} else {
that.shareInfo.path = 'pages/index/index';
}
uni.setStorageSync('shareInfo', that.shareInfo);
},
},
// #ifdef MP-WEIXIN
onShareAppMessage(res) {
let that = this;
return {
title: that.shareInfo.title,
path: that.shareInfo.path,
imageUrl: that.shareInfo.imageUrl,
success(res) {
uni.showToast({
title: '分享成功'
})
},
fail(res) {
uni.showToast({
title: '分享失败',
icon: 'none'
})
},
complete() {}
}
},
onShareTimeline(res) {
let that = this;
let query = '';
//携带当前页面资源ID参数
let currentPage = getCurrentPages()[getCurrentPages().length - 1];
let options = currentPage.options;
if (JSON.stringify(options) != '{}' && options.id) {
query += `id=${options.id}`;
}
let shareInfoUrl = that.shareInfo.path.split('?');
if (shareInfoUrl.length > 1) {
if (query !== '') {
query += '&';
}
query += shareInfoUrl[1];
}
return {
title: that.shareInfo.title,
query: query,
imageUrl: that.shareInfo.imageUrl,
success(res) {
uni.showToast({
title: '分享成功'
})
},
fail(res) {
uni.showToast({
title: '分享失败',
icon: 'none'
})
},
complete() {}
}
}
// #endif
}

340
nx/utils/tools.js Normal file
View File

@@ -0,0 +1,340 @@
export default {
isNullOrEmpty: function (value) {
//是否为空
return value === null || value === '' || value === undefined ? true : false
},
trim: function (value) {
//去空格
return value.replace(/(^\s*)|(\s*$)/g, '')
},
isMobile: function (value) {
//是否为手机号
return /^(?:13\d|14\d|15\d|16\d|17\d|18\d|19\d)\d{5}(\d{3}|\*{3})$/.test(value)
},
isFloat: function (value) {
//金额,只允许保留两位小数
return /^([0-9]*[.]?[0-9])[0-9]{0,1}$/.test(value)
},
isNum: function (value) {
//是否全为数字
return /^[0-9]+$/.test(value)
},
checkPwd: function (value) {
//密码为8~20位数字和字母组合
return /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,20}$/.test(value)
},
formatNum: function (num) {
//格式化手机号码
if (utils.isMobile(num)) {
num = num.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2')
}
return num
},
rmoney: function (money) {
//金额格式化
return parseFloat(money)
.toFixed(2)
.toString()
.split('')
.reverse()
.join('')
.replace(/(\d{3})/g, '$1,')
.replace(/\,$/, '')
.split('')
.reverse()
.join('')
},
copyText(text) {
let inputElement = document.createElement('input')
inputElement.value = text
document.body.appendChild(inputElement)
inputElement.select() //选中文本
document.execCommand('copy') //执行浏览器复制命令
inputElement.remove()
},
/**
* fn检测图片协议主要用于检测海报图片协议。
* param(imgPath): 图片地址。
*/
checkImgHttp(imgPath) {
let newPath = ''
let pathArr = imgPath.split('://')
// #ifdef H5
let ishttps = 'https:' == window.location.protocol ? true : false
ishttps ? (pathArr[0] = 'https') : (pathArr[0] = 'http')
// #endif
// #ifdef MP-WEIXIN
pathArr[0] = 'https'
// #endif
newPath = pathArr.join('://')
return newPath
},
// 打电话
callPhone(phoneNumber = '') {
let num = phoneNumber.toString()
uni.makePhoneCall({
phoneNumber: num,
fail(err) {
console.log('makePhoneCall出错', err)
}
})
},
// 图片处理-选择图片
chooseImage(count = 1) {
return new Promise((resolve, reject) => {
uni.chooseImage({
count: count, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: res => {
resolve(res.tempFilePaths)
}
})
}).catch(e => {
reject(e)
})
},
// 图片处理-上传图片
uploadImage(api, url) {
let config_url = API_URL
uni.showLoading({
title: '上传中'
})
return new Promise((resolve, reject) => {
uni.uploadFile({
url: config_url + api,
filePath: url,
name: 'file',
success: res => {
res = JSON.parse(res.data)
if (res.code === 1) {
uni.hideLoading()
uni.showToast({
title: '上传成功',
icon: 'none'
})
resolve(res.data)
} else {
uni.hideLoading()
uni.showModal({
title: '上传失败',
content: res.msg
})
}
}
})
}).catch(e => {
reject(e)
})
},
// 图片处理-预览图片
previewImage(urls = [], current = 0) {
uni.previewImage({
urls: urls,
current: current,
indicator: 'default',
loop: true,
fail(err) {
console.log('previewImage出错', urls, err)
}
})
},
// 图片处理-获取图片信息
getImageInfo(src = '') {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: src,
success: image => {
resolve(image)
},
fail(err) {
console.log('getImageInfo出错', src, err)
}
})
}).catch(e => {
reject(e)
})
},
/**
* 格式化时间
*/
//时间格式化 天时分秒
format(t) {
let format = {
d: '00',
h: '00',
m: '00',
s: '00'
}
if (t > 0) {
let d = Math.floor(t / 86400)
let h = Math.floor((t / 3600) % 24)
let m = Math.floor((t / 60) % 60)
let s = Math.floor(t % 60)
format.d = d < 10 ? '0' + d : d
format.h = h < 10 ? '0' + h : h
format.m = m < 10 ? '0' + m : m
format.s = s < 10 ? '0' + s : s
}
return format
},
//时间格式化(格式化最大为小时)
formatToHours(t) {
let format = {
d: '00',
h: '00',
m: '00',
s: '00'
}
if (t > 0) {
let h = Math.floor(t / 3600)
let m = Math.floor((t / 60) % 60)
let s = Math.floor(t % 60)
format.h = h < 10 ? '0' + h : h
format.m = m < 10 ? '0' + m : m
format.s = s < 10 ? '0' + s : s
}
return format
},
// 年月日
timestamp(timestamp) {
let date = new Date(timestamp * 1000) //根据时间戳生成的时间对象
let y = date.getFullYear()
let m = date.getMonth() + 1
let d = date.getDate()
m = m < 10 ? '0' + m : m
d = d < 10 ? '0' + d : d
let dateText = y + '-' + m + '-' + d
return dateText
},
// 年月日,时分秒
// "YYYY-mm-dd HH:MM"
dateFormat(fmt, date) {
let ret
const opt = {
'Y+': date.getFullYear().toString(), // 年
'm+': (date.getMonth() + 1).toString(), // 月
'd+': date.getDate().toString(), // 日
'H+': date.getHours().toString(), // 时
'M+': date.getMinutes().toString(), // 分
'S+': date.getSeconds().toString() // 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
}
for (let k in opt) {
ret = new RegExp('(' + k + ')').exec(fmt)
if (ret) {
fmt = fmt.replace(ret[1], ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0'))
}
}
return fmt
},
/**
* @fn 时间间隔格式化
* @param {*} startTime 开始时间的时间戳
* @param {*} endTime 结束时间的时间戳
* @return {string} str 返回时间字符串
*/
getTimeInterval(startTime, endTime) {
let runTime = parseInt((endTime - startTime) / 1000)
let year = Math.floor(runTime / 86400 / 365)
runTime = runTime % (86400 * 365)
let month = Math.floor(runTime / 86400 / 30)
runTime = runTime % (86400 * 30)
let day = Math.floor(runTime / 86400)
runTime = runTime % 86400
let hour = Math.floor(runTime / 3600)
runTime = runTime % 3600
let minute = Math.floor(runTime / 60)
runTime = runTime % 60
let second = runTime
let str = ''
if (year > 0) {
str = year + '年'
}
if (year <= 0 && month > 0) {
str = month + '月'
}
if (year <= 0 && month <= 0 && day > 0) {
str = day + '天'
}
if (year <= 0 && month <= 0 && day <= 0 && hour > 0) {
str = hour + '小时'
}
if (year <= 0 && month <= 0 && day <= 0 && hour <= 0 && minute > 0) {
str = minute + '分钟'
}
if (year <= 0 && month <= 0 && day <= 0 && hour <= 0 && minute <= 0 && second > 0) {
str += second + '秒'
}
str += '前'
return str
},
/**提示框
*title(标题)
*icon(图标): successloadingnone
*duration(延时): 0为不关闭, 毫秒数
*options(其它参数)
*/
msg(title, duration = 2000, mask = false, icon = 'none') {
//统一提示方便全局修改
if (Boolean(title) === false) {
return
}
uni.showToast({
title,
duration,
mask,
icon
})
},
/**
* @description 弹窗提示 showModal
*/
showModal(content, callback) {
uni.showModal({
title: '提示',
content: content,
showCancel: false,
success(res) {
if (res.confirm) {
if (typeof callback === 'function') {
callback()
}
} else if (res.cancel) {
}
}
})
},
isRsk() {
let sysInfo = uni.getSystemInfoSync()
let brand = sysInfo.brand.toLowerCase()
if (sysInfo.platform == 'android' && brand.indexOf('qualcomm') > -1) {
return true
}
return false
},
// 自定义 replacer将函数转换为字符串。json序列化和反序列化时避免函数丢失
replacer(key, value) {
if (typeof value === 'function') {
return value.toString()
}
return value
},
// 自定义 reviver将字符串转换回函数.json序列化和反序列化时避免函数丢失
reviver(key, value) {
const functionKeys = ['change', 'dicFormatter', 'click', 'focus', 'blur']
if (functionKeys.includes(key)) {
// 将字符串转换为函数
return new Function('return ' + value)()
}
return value
}
}

35
nx/wechat/wechat.js Normal file
View File

@@ -0,0 +1,35 @@
export default {
// #ifdef MP-WEIXIN
// 小程序更新
checkMiniProgramUpdate() {
if (uni.canIUse("getUpdateManager")) {
const updateManager = uni.getUpdateManager();
updateManager.onCheckForUpdate(function(res) {
// 请求完新版本信息的回调
if (res.hasUpdate) {
updateManager.onUpdateReady(function() {
uni.showModal({
title: "更新提示",
content: "新版本已经准备好,是否重启应用?",
success: function(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
}
});
});
updateManager.onUpdateFailed(function() {
// 新的版本下载失败
uni.showModal({
title: "已经有新版本了哟~",
content: "新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~"
});
});
}
});
}
},
// #endif
};