├── README.md ├── app.js ├── app.json ├── assets └── background.jpg ├── pages ├── index │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss └── utils │ ├── detectface.js │ └── md5.js └── project.config.json /README.md: -------------------------------------------------------------------------------- 1 | *BEAUTY* ![](https://img.shields.io/badge/license-MIT-0a7bbd.svg?longCache=true&style=flat-square) 2 | 3 | *** 4 | 5 | ### 说明 6 | 7 | 这个小程序是在前人的基础上修改的,说白了就是我复制过来修改代码,然后上线的。 8 | 9 | 小程序的样子是在 [weapp-beauty](https://github.com/zce/weapp-beauty/) 的基础上进行修改的,不过原作者不是调用 API 的,我这里修改成了调用 API 。 10 | 11 | > [https://github.com/zce/weapp-beauty](https://github.com/zce/weapp-beauty/) 12 | 13 | 过程中使用了下面这个库的代码,用来进行 md5 编码 14 | 15 | > [https://github.com/youngjuning/wxMD5](https://github.com/youngjuning/wxMD5) 16 | 17 | 还用了别的代码的,可是电脑用的谷歌浏览器出问题了,OneTab 的记录全没了,要是以后能找到的话,我补上。 18 | 19 | 需要去 [https://ai.qq.com](https://ai.qq.com)那创建应用,接入人脸检测与分析这个 API,最后去修改 detectface.js 那的 app_id 和 app_key 。 20 | 21 | ![detectface.js](https://upload-images.jianshu.io/upload_images/2989110-5762bd81d43ef544.png) 22 | 23 | index.js 里的 detectImage 函数可以注释掉或者直接去掉,实际上是用不到的,我保留下来只是为了顺便看一下原作者的代码。 24 | 25 | ![](https://upload-images.jianshu.io/upload_images/2989110-b748ff37c7ef3014.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 26 | 27 | ### 试例 28 | 29 | 此处的男性是[即刻 CEO](https://web.okjike.com/user/82D23B32-CF36-4C59-AD6F-D05E3552CBF3),希望我不会被打 30 | 31 | ![试例图片](https://upload-images.jianshu.io/upload_images/2989110-1bc38437a9849605.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 32 | 33 | ![小程序二维码](https://upload-images.jianshu.io/upload_images/2989110-08dc8b90fedfca54.jpg) 34 | 35 | 36 | 37 | [小程序『颜值检测仪』使用教程兼示范](https://www.bilibili.com/video/av35734615) 38 | 39 | ### TODO 40 | 41 | - [ ] 把 readme 写好,未完成; 42 | - [ ] 识别后的分享海报,未完成; 43 | 44 | 另一个小程序『恶搞二维码』已经开源了,要不点击[查看一下说明](https://mp.weixin.qq.com/s/W_Mj5_TjSSJjoe6kfDpU5w),然后再看看代码? 45 | 46 | > [https://github.com/weijunzii/Spoof-QRcode](https://github.com/weijunzii/Spoof-QRcode ) -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | App({ 2 | /** 3 | * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) 4 | */ 5 | onLaunch: function () { 6 | 7 | }, 8 | 9 | /** 10 | * 当小程序启动,或从后台进入前台显示,会触发 onShow 11 | */ 12 | onShow: function (options) { 13 | 14 | }, 15 | 16 | /** 17 | * 当小程序从前台进入后台,会触发 onHide 18 | */ 19 | onHide: function () { 20 | 21 | }, 22 | 23 | /** 24 | * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 25 | */ 26 | onError: function (msg) { 27 | 28 | }, 29 | base64:'' 30 | }) 31 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/index" 4 | ], 5 | "window": { 6 | "navigationBarBackgroundColor": "#ffffff", 7 | "navigationBarTextStyle": "black", 8 | "navigationBarTitleText": "测颜值", 9 | "navigationStyle": "custom", 10 | "backgroundColor": "#eeeeee", 11 | "backgroundTextStyle": "light", 12 | "enablePullDownRefresh": false 13 | } 14 | } -------------------------------------------------------------------------------- /assets/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weijunzii/beauty/30fc5367b685de3bd069129dc38784d7276d5917/assets/background.jpg -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | var md5 = require('../utils/md5.js') 2 | //var app = getApp() 3 | var detectface = require('../utils/detectface.js') 4 | Page({ 5 | /** 6 | * 页面的初始数据 7 | */ 8 | data: { 9 | // https://picsum.photos/1080/1920/?image=302 10 | // https://picsum.photos/1080/1920/?random 随机选择一张 1080*1920 的照片 11 | // https://source.unsplash.com/random/1080x1920 随机选择一张 1080*1920 的照片 12 | // 也可以使用本地的图片,如 /assets/background.jpg ,先建一个 assets 文件夹,然后放一张图 13 | image: 'https://picsum.photos/1080/1920/?random', 14 | result: null 15 | }, 16 | 17 | detectImage (src) { // 检测图片 18 | wx.showLoading({ title: '分析中...' }) 19 | 20 | const that = this 21 | 22 | wx.uploadFile({ // 上传图片 23 | url: 'https://ai.qq.com/cgi-bin/appdemo_detectface',//需要在小程序的开发设置那加上这个服务器域名 24 | filePath: src,//图片的路径,从 getImage 那获得 25 | name: 'image_file', 26 | success (res) { 27 | console.log('检测开始:') 28 | const result = JSON.parse(res.data) 29 | 30 | if (result.ret == 0) { 31 | console.log('检测成功:', res) 32 | } 33 | // 检测失败 34 | if (result.ret !== 0) { 35 | console.log('检测失败:', res) 36 | wx.showToast({ icon: 'none', title: '没找到你的小脸蛋,再来一次吧~' }) 37 | return false 38 | } 39 | 40 | that.setData({ result: result.data.face[0] }) 41 | wx.hideLoading() 42 | } 43 | }) 44 | }, 45 | 46 | bindConfirm(base64Img) { 47 | //const base64 = base64Img 48 | //console.log('base64在家吗', base64Img) 49 | const that = this 50 | base64Img = getApp() 51 | //base64Img =getApp().base64 52 | //console.log('base64Img在家吗', base64Img) 53 | //console.log('base64在家吗', base64Img.base64) 54 | wx.showLoading({ title: '分析中...' }) 55 | console.log('开始搞事') 56 | detectface.request(base64Img, { 57 | success(res) { 58 | console.log('可行') 59 | console.log('检测开始:') 60 | const result = (res.data) 61 | 62 | if (result.ret == 0) { 63 | console.log('检测成功:', res) 64 | } 65 | // 检测失败 66 | if (result.ret !== 0) { 67 | console.log('检测失败:', res) 68 | wx.showToast({ icon: 'none', title: '没找到你的小脸蛋,再来一次吧~' }) 69 | return false 70 | } 71 | that.setData({ result: result.data.face_list[0] }) 72 | wx.hideLoading() 73 | 74 | } 75 | }) 76 | }, 77 | 78 | 79 | getImage (type = 'camera') { //选取图片 80 | const that = this 81 | wx.chooseImage({ 82 | sizeType: ['compressed'], //original 原图,compressed 压缩图 83 | c: ['album', 'camera'],//album 从相册选图,camera 使用相机 84 | success(res) { 85 | const image = res.tempFiles[0] 86 | console.log(image) 87 | 88 | wx.getFileSystemManager().readFile({ 89 | filePath: res.tempFilePaths[0], 90 | encoding: 'base64', 91 | success(res) { 92 | var base64Img=getApp() 93 | base64Img.base64 = res.data 94 | //var base64 = res.data 95 | console.log('data:image/png;base64,' + res.data)//打印图片的base64编码 96 | that.bindConfirm(res.data) 97 | } 98 | }) 99 | 100 | // 图片过大 101 | if (image.size > 1024 * 1000) { 102 | console.log('图片过大,上传失败', res)//压缩了之后不会过大 103 | wx.showToast({ icon: 'none', title: '图片过大, 请重新拍张小的!' }) 104 | return false 105 | } 106 | 107 | that.setData({ image: image.path })//把选取到的图片作为背景图 108 | //console.log(image.path)//在控制台打印出文件的路径 109 | //that.detectImage(image.path)//把路径传到 detectImage 那 110 | //that.bindConfirm(res.data)//把 base64 传到 bindConfirm 那 111 | //console.log('不是的data:image/png;base64,' + res.data) 112 | } 113 | }) 114 | }, 115 | 116 | handleCamera () { 117 | this.getImage()//拍照 118 | }, 119 | // 因为我在 wx.chooseImage 那的 wx.chooseImage 两个都选择了,所以无论是点击还是长按,都是可以拍照和从相册选图的 120 | handleChoose () { 121 | this.getImage('album')//选取照片 122 | }, 123 | /** 124 | * 用户点击右上角分享 125 | */ 126 | onShareAppMessage () { 127 | if (this.data.result) { 128 | return { title: `刚刚测了自己的颜值为【${this.data.result.beauty}】你也赶紧来试试吧!` } 129 | } 130 | } 131 | }) 132 | 133 | /*还是可以改进的,比如 134 | https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014345008539155e93fc16046d4bb7854943814c4f9dc2000 135 | 136 | 我可以加用 Promise 封装微信小程序的 Request 请求,或者可以把 bindConfirm 的功能写入到 getImage 里面,以后有空就试试吧,希望不咕咕咕 137 | */ -------------------------------------------------------------------------------- /pages/index/index.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 性别:{{result.gender > 50 ? '男' : '女'}} 6 | 7 | 8 | 年龄:{{result.age}}岁 9 | 10 | 11 | 表情: 12 | 黯然伤神 13 | 半嗔半喜 14 | 似笑非笑 15 | 笑逐颜开 16 | 莞尔一笑 17 | 喜上眉梢 18 | 眉开眼笑 19 | 笑尽妖娆 20 | 心花怒放 21 | 一笑倾城 22 | 23 | 24 | 颜值:{{result.beauty}}(0~100) 25 | 26 | 27 | 姿势: 28 | {{result.pitch > 0 ? '低头' : '抬头'}} 29 | 30 | 偏头 31 | 侧颜杀 32 | 33 | 你好,带眼镜的朋友~ 34 | 35 | 36 | 37 | 41 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | .image { 2 | position: fixed; 3 | top: 0; 4 | width: 100%; 5 | height: 100%; 6 | z-index: -1; 7 | } 8 | 9 | .info { 10 | margin: 750rpx 30rpx 0; 11 | padding: 50rpx; /* */ 12 | border-radius: 20rpx; 13 | background: rgba(255, 255, 255, 0.95); 14 | font-size: 32rpx; 15 | line-height: 2; 16 | color: #495057; 17 | } 18 | 19 | .controls { 20 | position: fixed; 21 | bottom: 0; 22 | padding: 80rpx 0; 23 | width: 100%; 24 | } 25 | 26 | .btn-start { 27 | display: flex; 28 | align-items: center; 29 | justify-content: space-around; 30 | width: 330rpx; 31 | padding: 5rpx 45rpx; 32 | border-radius: 50rpx; 33 | background: rgba(73, 80, 87, 0.7); 34 | } 35 | 36 | .btn-start-hover { 37 | background: rgba(73, 80, 87, 0.9); 38 | } 39 | 40 | .btn-start .icon { 41 | width: 32rpx; 42 | height: 32rpx; 43 | background: url('data:image/svg+xml,'); 44 | } 45 | 46 | .btn-start .text { 47 | color: #fff; 48 | font-size: 30rpx; 49 | } -------------------------------------------------------------------------------- /pages/utils/detectface.js: -------------------------------------------------------------------------------- 1 | let md5 = require('./md5.js') 2 | let app_id = '你的 APPID' 3 | let app_key = '你的 APPKEY' 4 | let url = 'https://api.ai.qq.com/fcgi-bin/face/face_detectface' 5 | // 去 https://ai.qq.com/ 创建应用,接入人脸检测与分析这个 API 6 | // 需要在小程序的开发设置那加上这个服务器域名 7 | 8 | var request = function (base64Img, callback) { 9 | const that = this 10 | let params = { 11 | app_id: app_id, 12 | image: getApp().base64, 13 | nonce_str: Math.random().toString(36).substr(2), 14 | time_stamp: parseInt(new Date().getTime() / 1000).toString(), 15 | mode: '0',//关键点,检测模式,0-正常,1-大脸模式(默认1) 16 | } 17 | params['sign'] = _genRequestSign(params) 18 | wx.request({ 19 | url: url, 20 | data: params, 21 | header: { 22 | 'content-type': 'application/x-www-form-urlencoded' 23 | }, 24 | method: 'POST', 25 | success: function (res) { 26 | callback.success(res) 27 | //that.setData({ result: result.data.face[0] }) 28 | }, 29 | /*success: function (res) { 30 | callback.success(res) 31 | },*/ 32 | fail: function (res) { 33 | if (callback.fail) 34 | callback.fail() 35 | } 36 | }) 37 | } 38 | 39 | var _genRequestSign = function(params){ 40 | // 1. 对请求参数按字典升序排序 41 | params = _sortObject(params) 42 | // 2. 拼接键值对,value部分进行URL编码 43 | let paramStr = '' 44 | let keys = Object.keys(params) 45 | for (let idx in keys) { 46 | let key = keys[idx] 47 | paramStr += key + '=' + encodeURIComponent(params[key]) + '&' 48 | } 49 | // 3. 拼接key 50 | paramStr += 'app_key=' + app_key 51 | // 4. md5 52 | return md5.hexMD5(paramStr).toUpperCase() 53 | } 54 | 55 | var _sortObject = function(obj){ 56 | var keys = Object.keys(obj).sort() 57 | var newObj = {} 58 | for (var i = 0; i < keys.length; i++) { 59 | newObj[keys[i]] = obj[keys[i]] 60 | } 61 | return newObj 62 | } 63 | 64 | module.exports = { 65 | request: request 66 | } -------------------------------------------------------------------------------- /pages/utils/md5.js: -------------------------------------------------------------------------------- 1 | /* 2 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message 3 | * Digest Algorithm, as defined in RFC 1321. 4 | * Version 1.1 Copyright (C) Paul Johnston 1999 - 2002. 5 | * Code also contributed by Greg Holt 6 | * See http://pajhome.org.uk/site/legal.html for details. 7 | */ 8 | 9 | /* 10 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 11 | * to work around bugs in some JS interpreters. 12 | */ 13 | function safe_add(x, y) { 14 | var lsw = (x & 0xFFFF) + (y & 0xFFFF) 15 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16) 16 | return (msw << 16) | (lsw & 0xFFFF) 17 | } 18 | 19 | /* 20 | * Bitwise rotate a 32-bit number to the left. 21 | */ 22 | function rol(num, cnt) { 23 | return (num << cnt) | (num >>> (32 - cnt)) 24 | } 25 | 26 | /* 27 | * These functions implement the four basic operations the algorithm uses. 28 | */ 29 | function cmn(q, a, b, x, s, t) { 30 | return safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b) 31 | } 32 | function ff(a, b, c, d, x, s, t) { 33 | return cmn((b & c) | ((~b) & d), a, b, x, s, t) 34 | } 35 | function gg(a, b, c, d, x, s, t) { 36 | return cmn((b & d) | (c & (~d)), a, b, x, s, t) 37 | } 38 | function hh(a, b, c, d, x, s, t) { 39 | return cmn(b ^ c ^ d, a, b, x, s, t) 40 | } 41 | function ii(a, b, c, d, x, s, t) { 42 | return cmn(c ^ (b | (~d)), a, b, x, s, t) 43 | } 44 | 45 | /* 46 | * Calculate the MD5 of an array of little-endian words, producing an array 47 | * of little-endian words. 48 | */ 49 | function coreMD5(x) { 50 | var a = 1732584193 51 | var b = -271733879 52 | var c = -1732584194 53 | var d = 271733878 54 | 55 | for (var i = 0; i < x.length; i += 16) { 56 | var olda = a 57 | var oldb = b 58 | var oldc = c 59 | var oldd = d 60 | 61 | a = ff(a, b, c, d, x[i + 0], 7, -680876936) 62 | d = ff(d, a, b, c, x[i + 1], 12, -389564586) 63 | c = ff(c, d, a, b, x[i + 2], 17, 606105819) 64 | b = ff(b, c, d, a, x[i + 3], 22, -1044525330) 65 | a = ff(a, b, c, d, x[i + 4], 7, -176418897) 66 | d = ff(d, a, b, c, x[i + 5], 12, 1200080426) 67 | c = ff(c, d, a, b, x[i + 6], 17, -1473231341) 68 | b = ff(b, c, d, a, x[i + 7], 22, -45705983) 69 | a = ff(a, b, c, d, x[i + 8], 7, 1770035416) 70 | d = ff(d, a, b, c, x[i + 9], 12, -1958414417) 71 | c = ff(c, d, a, b, x[i + 10], 17, -42063) 72 | b = ff(b, c, d, a, x[i + 11], 22, -1990404162) 73 | a = ff(a, b, c, d, x[i + 12], 7, 1804603682) 74 | d = ff(d, a, b, c, x[i + 13], 12, -40341101) 75 | c = ff(c, d, a, b, x[i + 14], 17, -1502002290) 76 | b = ff(b, c, d, a, x[i + 15], 22, 1236535329) 77 | 78 | a = gg(a, b, c, d, x[i + 1], 5, -165796510) 79 | d = gg(d, a, b, c, x[i + 6], 9, -1069501632) 80 | c = gg(c, d, a, b, x[i + 11], 14, 643717713) 81 | b = gg(b, c, d, a, x[i + 0], 20, -373897302) 82 | a = gg(a, b, c, d, x[i + 5], 5, -701558691) 83 | d = gg(d, a, b, c, x[i + 10], 9, 38016083) 84 | c = gg(c, d, a, b, x[i + 15], 14, -660478335) 85 | b = gg(b, c, d, a, x[i + 4], 20, -405537848) 86 | a = gg(a, b, c, d, x[i + 9], 5, 568446438) 87 | d = gg(d, a, b, c, x[i + 14], 9, -1019803690) 88 | c = gg(c, d, a, b, x[i + 3], 14, -187363961) 89 | b = gg(b, c, d, a, x[i + 8], 20, 1163531501) 90 | a = gg(a, b, c, d, x[i + 13], 5, -1444681467) 91 | d = gg(d, a, b, c, x[i + 2], 9, -51403784) 92 | c = gg(c, d, a, b, x[i + 7], 14, 1735328473) 93 | b = gg(b, c, d, a, x[i + 12], 20, -1926607734) 94 | 95 | a = hh(a, b, c, d, x[i + 5], 4, -378558) 96 | d = hh(d, a, b, c, x[i + 8], 11, -2022574463) 97 | c = hh(c, d, a, b, x[i + 11], 16, 1839030562) 98 | b = hh(b, c, d, a, x[i + 14], 23, -35309556) 99 | a = hh(a, b, c, d, x[i + 1], 4, -1530992060) 100 | d = hh(d, a, b, c, x[i + 4], 11, 1272893353) 101 | c = hh(c, d, a, b, x[i + 7], 16, -155497632) 102 | b = hh(b, c, d, a, x[i + 10], 23, -1094730640) 103 | a = hh(a, b, c, d, x[i + 13], 4, 681279174) 104 | d = hh(d, a, b, c, x[i + 0], 11, -358537222) 105 | c = hh(c, d, a, b, x[i + 3], 16, -722521979) 106 | b = hh(b, c, d, a, x[i + 6], 23, 76029189) 107 | a = hh(a, b, c, d, x[i + 9], 4, -640364487) 108 | d = hh(d, a, b, c, x[i + 12], 11, -421815835) 109 | c = hh(c, d, a, b, x[i + 15], 16, 530742520) 110 | b = hh(b, c, d, a, x[i + 2], 23, -995338651) 111 | 112 | a = ii(a, b, c, d, x[i + 0], 6, -198630844) 113 | d = ii(d, a, b, c, x[i + 7], 10, 1126891415) 114 | c = ii(c, d, a, b, x[i + 14], 15, -1416354905) 115 | b = ii(b, c, d, a, x[i + 5], 21, -57434055) 116 | a = ii(a, b, c, d, x[i + 12], 6, 1700485571) 117 | d = ii(d, a, b, c, x[i + 3], 10, -1894986606) 118 | c = ii(c, d, a, b, x[i + 10], 15, -1051523) 119 | b = ii(b, c, d, a, x[i + 1], 21, -2054922799) 120 | a = ii(a, b, c, d, x[i + 8], 6, 1873313359) 121 | d = ii(d, a, b, c, x[i + 15], 10, -30611744) 122 | c = ii(c, d, a, b, x[i + 6], 15, -1560198380) 123 | b = ii(b, c, d, a, x[i + 13], 21, 1309151649) 124 | a = ii(a, b, c, d, x[i + 4], 6, -145523070) 125 | d = ii(d, a, b, c, x[i + 11], 10, -1120210379) 126 | c = ii(c, d, a, b, x[i + 2], 15, 718787259) 127 | b = ii(b, c, d, a, x[i + 9], 21, -343485551) 128 | 129 | a = safe_add(a, olda) 130 | b = safe_add(b, oldb) 131 | c = safe_add(c, oldc) 132 | d = safe_add(d, oldd) 133 | } 134 | return [a, b, c, d] 135 | } 136 | 137 | /* 138 | * Convert an array of little-endian words to a hex string. 139 | */ 140 | function binl2hex(binarray) { 141 | var hex_tab = "0123456789abcdef" 142 | var str = "" 143 | for (var i = 0; i < binarray.length * 4; i++) { 144 | str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) + 145 | hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF) 146 | } 147 | return str 148 | } 149 | 150 | /* 151 | * Convert an array of little-endian words to a base64 encoded string. 152 | */ 153 | function binl2b64(binarray) { 154 | var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 155 | var str = "" 156 | for (var i = 0; i < binarray.length * 32; i += 6) { 157 | str += tab.charAt(((binarray[i >> 5] << (i % 32)) & 0x3F) | 158 | ((binarray[i >> 5 + 1] >> (32 - i % 32)) & 0x3F)) 159 | } 160 | return str 161 | } 162 | 163 | /* 164 | * Convert an 8-bit character string to a sequence of 16-word blocks, stored 165 | * as an array, and append appropriate padding for MD4/5 calculation. 166 | * If any of the characters are >255, the high byte is silently ignored. 167 | */ 168 | function str2binl(str) { 169 | var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks 170 | var blks = new Array(nblk * 16) 171 | for (var i = 0; i < nblk * 16; i++) blks[i] = 0 172 | for (var i = 0; i < str.length; i++) 173 | blks[i >> 2] |= (str.charCodeAt(i) & 0xFF) << ((i % 4) * 8) 174 | blks[i >> 2] |= 0x80 << ((i % 4) * 8) 175 | blks[nblk * 16 - 2] = str.length * 8 176 | return blks 177 | } 178 | 179 | /* 180 | * Convert a wide-character string to a sequence of 16-word blocks, stored as 181 | * an array, and append appropriate padding for MD4/5 calculation. 182 | */ 183 | function strw2binl(str) { 184 | var nblk = ((str.length + 4) >> 5) + 1 // number of 16-word blocks 185 | var blks = new Array(nblk * 16) 186 | for (var i = 0; i < nblk * 16; i++) blks[i] = 0 187 | for (var i = 0; i < str.length; i++) 188 | blks[i >> 1] |= str.charCodeAt(i) << ((i % 2) * 16) 189 | blks[i >> 1] |= 0x80 << ((i % 2) * 16) 190 | blks[nblk * 16 - 2] = str.length * 16 191 | return blks 192 | } 193 | 194 | /* 195 | * External interface 196 | */ 197 | function hexMD5(str) { return binl2hex(coreMD5(str2binl(str))) } 198 | function hexMD5w(str) { return binl2hex(coreMD5(strw2binl(str))) } 199 | function b64MD5(str) { return binl2b64(coreMD5(str2binl(str))) } 200 | function b64MD5w(str) { return binl2b64(coreMD5(strw2binl(str))) } 201 | /* Backward compatibility */ 202 | function calcMD5(str) { return binl2hex(coreMD5(str2binl(str))) } 203 | module.exports = { 204 | hexMD5: hexMD5 205 | } -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件。", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "setting": { 7 | "urlCheck": true, 8 | "es6": true, 9 | "postcss": true, 10 | "minified": true, 11 | "newFeature": true 12 | }, 13 | "compileType": "miniprogram", 14 | "libVersion": "2.0.4", 15 | "appid": "wx9466ec1f37f1af95", 16 | "projectname": "beauty", 17 | "isGameTourist": false, 18 | "condition": { 19 | "search": { 20 | "current": -1, 21 | "list": [] 22 | }, 23 | "conversation": { 24 | "current": -1, 25 | "list": [] 26 | }, 27 | "game": { 28 | "currentL": -1, 29 | "list": [] 30 | }, 31 | "miniprogram": { 32 | "current": -1, 33 | "list": [] 34 | } 35 | } 36 | } --------------------------------------------------------------------------------