chengjie 7 年 前
コミット
918e701b7b
共有28 個のファイルを変更した3807 個の追加101 個の削除を含む
  1. 20 3
      app.js
  2. 2 1
      app.json
  3. 14 0
      app.wxss
  4. BIN
      images/print.png
  5. 77 52
      pages/index/index.js
  6. 3 3
      pages/index/index.json
  7. 4 5
      pages/index/index.wxml
  8. 4 26
      pages/index/index.wxss
  9. 103 0
      pages/index/list.js
  10. 1 0
      pages/index/list.json
  11. 32 0
      pages/index/list.wxml
  12. 59 0
      pages/index/list.wxss
  13. 17 0
      utils/cryptojs.js
  14. 402 0
      utils/lib/AES.js
  15. 378 0
      utils/lib/BlockModes.js
  16. 155 0
      utils/lib/Crypto.js
  17. 37 0
      utils/lib/CryptoMath.js
  18. 1003 0
      utils/lib/DES.js
  19. 38 0
      utils/lib/HMAC.js
  20. 117 0
      utils/lib/MARC4.js
  21. 158 0
      utils/lib/MD5.js
  22. 49 0
      utils/lib/PBKDF2.js
  23. 88 0
      utils/lib/PBKDF2Async.js
  24. 221 0
      utils/lib/Rabbit.js
  25. 86 0
      utils/lib/SHA1.js
  26. 130 0
      utils/lib/SHA256.js
  27. 311 0
      utils/main.js
  28. 298 11
      utils/util.js

+ 20 - 3
app.js

@@ -1,11 +1,28 @@
1 1
 //app.js
2 2
 App({
3
-  onLaunch: function () {
4
-
3
+  onLaunch: function (options) {
4
+    this.getSystemInfo();
5
+    if (options && options.scene) {
6
+      console.log("scene:" + options.scene);
7
+      this.globalData.userSource = options.scene;
8
+    }
9
+    if (options && options.shareTicket) {
10
+      this.globalData.shareTicket = options.shareTicket;
11
+    }
12
+  },
13
+  getSystemInfo: function () {
14
+    this.globalData.systemInfo = wx.getSystemInfoSync();
5 15
   },
6 16
   globalData: {
7 17
     version: "0.1.3",
8
-    userInfo: null,
18
+    IsProduction: true,
9 19
     ProgramID: 105,
20
+    StartSecond: 4,
21
+    fileUrl: "https://kylx365-1253256735.file.myqcloud.com/",
22
+    serverUrl: "https://www.kylx365.com/apiData/",
23
+    serverUrlServer: "https://www.kylx365.com/apiData/",
24
+    serverUrlLocalhost: "http://localhost:3020/apiData/",
25
+    Key: "kylx365_chengjie",
26
+    IV: "kylx365hongliren",
10 27
   }
11 28
 })

+ 2 - 1
app.json

@@ -1,6 +1,7 @@
1 1
 {
2 2
   "pages": [
3
-    "pages/index/index"
3
+    "pages/index/index",
4
+    "pages/index/list"
4 5
   ],
5 6
   "window": {
6 7
     "backgroundTextStyle": "light",

+ 14 - 0
app.wxss

@@ -24,3 +24,17 @@
24 24
   align-items: center;
25 25
   justify-content: center;
26 26
 }
27
+
28
+.Left{
29
+  margin-left: 30rpx;
30
+  justify-content: flex-start;
31
+}
32
+
33
+.Right{
34
+  margin-right: 30rpx;
35
+  justify-content: flex-end;
36
+}
37
+
38
+.Width100{
39
+  width:100%;
40
+}

BIN
images/print.png


+ 77 - 52
pages/index/index.js

@@ -1,74 +1,99 @@
1
+import common from '../../utils/util';
2
+import server from '../../utils/main';
3
+
1 4
 const app = getApp()
2 5
 Page({
3 6
   data: {
4 7
     version: app.globalData.version,
8
+    FileUrl: app.globalData.fileUrl,
5 9
   },
6 10
   onLoad: function () {
7
-    var list = this.getProgramList();
8
-    this.setData({
9
-      List: list,
11
+    var that=this;
12
+    that.getEnumerationData(function(){
13
+      that.getQuestionTypesList(function(){
14
+        var data = wx.getStorageSync('QuestionTypeList');
15
+        that.setData({
16
+          QuestionCategory: data,
17
+          Containnerheight: common.getSystemHeight(),
18
+
19
+        });
20
+      });
10 21
     });
22
+  },
23
+  gotoList:function(e){
24
+    var questionTypeID = e.currentTarget.dataset.id;
25
+    wx.navigateTo({
26
+      url: './list?id=' + questionTypeID
27
+    });
28
+  },
29
+  //得到题型数据列表
30
+  getQuestionTypesList: function (callback) {
31
+    server.getData('GetQuestionTypes', function (data) {
32
+      var QuestionTypeList = data;
11 33
 
12
-    var obj = {
13
-      currentTarget: {
14
-        dataset: {
15
-          appid: list[3].appId,
16
-          path: list[3].path,
34
+      QuestionTypeList[QuestionTypeList.length - 1].List[QuestionTypeList[QuestionTypeList.length - 1].List.length - 1].NextID = QuestionTypeList[0].List[0].ID
35
+      for (var i = 0; i < QuestionTypeList.length; i++) {
36
+        if (i > 0)
37
+          QuestionTypeList[i - 1].List[QuestionTypeList[i - 1].List.length - 1].NextID = QuestionTypeList[i].List[0].ID
38
+        for (var j = 1; j < QuestionTypeList[i].List.length; j++) {
39
+          QuestionTypeList[i].List[j - 1].NextID = QuestionTypeList[i].List[j].ID;
17 40
         }
18 41
       }
19
-    }
20
-    this.goto(obj);
21
-  },
22
-  goto: function (e) {
23
-    var appid = e.currentTarget.dataset.appid;
24
-    var path = e.currentTarget.dataset.path;
25
-    wx.navigateToMiniProgram({
26
-      appId: appid,
27
-      path: path,
28
-      extraData: {
29
-      },
30
-      success(res) {
31
-        // 打开成功
42
+      //格式化或补充数据
43
+      for (var i = 0; i < QuestionTypeList.length; i++) {
44
+        for (var j = 0; j < QuestionTypeList[i].List.length; j++) {
45
+          var item = QuestionTypeList[i].List[j];
46
+          item.DifficultyName = common.getEnumerationName(item.Difficulty, app.globalData.Enumeration);
47
+        }
32 48
       }
49
+
50
+      wx.setStorage({
51
+        key: "QuestionTypeList",
52
+        data: data
53
+      });
54
+      callback();
33 55
     });
34 56
   },
35
-  getProgramList: function () {
36
-    return [
37
-      {
38
-        ImageUrl: "0101.png",
39
-        appId: 'wx46a7b4c420e6d38f',
40
-        path: 'pages/index/start?SourceID=' + app.globalData.ProgramID,
57
+  //得到枚举数据
58
+  getEnumerationData: function (callback) {
59
+    server.getData('GetEnumerationList', function (data) {
60
+      app.globalData.Enumeration = data;
61
+      wx.setStorage({
62
+        key: "Enumeration",
63
+        data: data
64
+      });
65
+      callback();
66
+    });
67
+  },
68
+  updateProgram: function () {
69
+    if (wx.canIUse("getUpdateManager")) {
70
+      const updateManager = wx.getUpdateManager();
41 71
 
42
-      },
43
-      {
44
-        ImageUrl: "0103.png",
45
-        appId: 'wx313a8f2c0741efe1',
46
-        path: 'pages/index/index?SourceID=' + app.globalData.ProgramID,
47
-      },
48
-      {
49
-        ImageUrl: "0102.png",
50
-        appId: 'wx331e8dd070f01d0e',
51
-        path: 'pages/index/index?SourceID=' + app.globalData.ProgramID,
52
-      },
53
-      {
54
-        ImageUrl: "0104.png",
55
-        appId: 'wxb54a6d5aff836ee3',
56
-        path: 'pages/index/index?SourceID=' + app.globalData.ProgramID,
57
-      },
58
-      {
59
-        ImageUrl: "0105.png",
60
-        appId: 'wxa5e33c61fe37dd01',
61
-        path: 'pages/index/index?SourceID=' + app.globalData.ProgramID,
62
-      },
63
-    ];
72
+      updateManager.onCheckForUpdate(function (res) {
73
+        // 请求完新版本信息的回调
74
+        console.log(res.hasUpdate)
75
+      });
76
+
77
+      updateManager.onUpdateReady(function () {
78
+        wx.showModal({
79
+          title: '更新提示',
80
+          content: '新版本已经准备好,是否重启应用?',
81
+          success: function (res) {
82
+            if (res.confirm) {
83
+              // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
84
+              updateManager.applyUpdate()
85
+            }
86
+          }
87
+        });
88
+
89
+      });
90
+    }
64 91
   },
65 92
   onShareAppMessage: function () {
66 93
     return {
67
-      title: '英语自然拼读',
94
+      title: '',
68 95
       path: 'pages/index/index',
69
-      imageUrl: '../../images/108.png',
70 96
       success: function (res) {
71
-        server.shareGroup(res);
72 97
       },
73 98
       fail: function (err) {
74 99
         console.log(err);

+ 3 - 3
pages/index/index.json

@@ -1,7 +1,7 @@
1 1
 {
2
-  "navigationBarBackgroundColor": "#003579",
3
-  "navigationBarTextStyle": "#fff",
4
-  "navigationBarTitleText": "唱意教育系列产品",
2
+  "navigationBarBackgroundColor": "#fff",
3
+  "navigationBarTextStyle": "black",
4
+  "navigationBarTitleText": "小学数学计算题大全",
5 5
   "backgroundColor": "#1E1E1E",
6 6
   "backgroundTextStyle": "light",
7 7
   "enablePullDownRefresh": false

+ 4 - 5
pages/index/index.wxml

@@ -1,6 +1,5 @@
1
-<view class="container FlexColumn" style='height:{{Height}}rpx;'>
2
-  <view class="line"></view>
3
-  <view class="line2"></view>
4
-  <image wx:for="{{List}}" wx:key="index" class="btn" src="../../images/{{item.ImageUrl}}" bindtap='goto' data-appid="{{item.appId}}" data-path="{{item.path}}" />
5
-  <text class="bottom">©2014-2018 小学生素质练习系列产品\n微信小程序 版本 {{version}}</text>
1
+<view class="container FlexColumn">
2
+  <block wx:for="{{QuestionCategory}}" wx:key="index">
3
+    <image src="{{FileUrl}}images/QuestionLibrary/{{item.ImageUrl}}?2" class="QuestionTypeImage" bindtap="gotoList" data-id="{{item.ID}}" />
4
+  </block>
6 5
 </view>

+ 4 - 26
pages/index/index.wxss

@@ -3,30 +3,8 @@
3 3
   justify-content: flex-start;
4 4
 } 
5 5
 
6
-.line{
6
+.QuestionTypeImage{
7 7
   width: 100%;
8
-  height:30rpx;
9
-  background-color: #00214C;
10
-  position: fixed;
11
-  top:0;
12
-}
13
-
14
-.line2{
15
-  width: 100%;
16
-  height:30rpx;
17
-  background-color: #1E1E1E;
18
-  margin-bottom: 30rpx;
19
-}
20
-
21
-.btn {
22
-  height:350rpx;
23
-  width:710rpx;
24
-  margin-bottom: 20rpx;
25
-}
26
-
27
-.bottom{
28
-  font-size:20rpx;
29
-  color:#fff;
30
-  text-align: center;
31
-  margin: 60rpx 0 40rpx 0;
32
-}
8
+  height:400rpx;
9
+  position: relative;
10
+}

+ 103 - 0
pages/index/list.js

@@ -0,0 +1,103 @@
1
+import common from '../../utils/util';
2
+import server from '../../utils/main';
3
+
4
+var app = getApp();
5
+var category = 0;
6
+
7
+Page({
8
+
9
+  /**
10
+   * 页面的初始数据
11
+   */
12
+  data: {
13
+    FileUrl: app.globalData.fileUrl,
14
+  },
15
+
16
+  /**
17
+   * 生命周期函数--监听页面加载
18
+   */
19
+  onLoad: function (options) {
20
+    this.setData({
21
+      Containnerheight: server.getWindowHeight(),
22
+    });
23
+    category = options.id;
24
+    console.log(category);
25
+    this.getList();
26
+  },
27
+
28
+  onPullDownRefresh: function () {
29
+    this.getList();
30
+  },
31
+
32
+  onShow: function () {
33
+    var that = this;
34
+    that.getList();
35
+  },
36
+
37
+  getList: function () {
38
+    this.setData({
39
+      Level: category,
40
+    });
41
+
42
+    var data = wx.getStorageSync('QuestionTypeList');
43
+    for (var i = 0; i < data.length; i++) {
44
+      if (data[i].ID == category) {
45
+        
46
+        this.setData({
47
+          QuestionTypeList: data[i].List,
48
+        });
49
+        wx.setNavigationBarTitle({
50
+          title: data[i].Name,
51
+        });
52
+        break;
53
+      }
54
+    }
55
+  },
56
+  gotoPrint: function (e) {
57
+    var that=this;
58
+    var id = e.currentTarget.dataset.id;
59
+    server.getData('GetQuestionTypesPrint?ID='+id, function (data) {
60
+      that.downImage(data);
61
+    });
62
+  },
63
+  downImage:function(filename){
64
+    var that = this;
65
+    wx.showLoading({
66
+      title: '下载中',
67
+    });
68
+    setTimeout(function(){
69
+      wx.downloadFile({
70
+        url: "https://print-1253256735.file.myqcloud.com/" + filename + ".png",
71
+        success: function (res) {
72
+          wx.hideLoading();
73
+          wx.previewImage({
74
+            current: res.tempFilePath, // 当前显示图片的http链接
75
+            urls: [res.tempFilePath] // 需要预览的图片http链接列表
76
+          })
77
+        },
78
+        fail: function () {
79
+          wx.hideLoading();
80
+          that.downImage(filename);
81
+        }
82
+      });
83
+    },2000);
84
+  },
85
+  onShareAppMessage: function () {
86
+    var that = this;
87
+    return {
88
+      title: '',
89
+      path: 'pages/index/start?UserID=' + app.globalData.userInfo.UserID,
90
+      imageUrl: app.globalData.fileUrl + 'images3/Extend/02.png',
91
+      success: function (res) {
92
+        
93
+      },
94
+      fail: function (err) {
95
+        console.log(err);
96
+      },
97
+      complete: function (res) {
98
+        console.log("shareComplete:" + res);
99
+      },
100
+    }
101
+  },
102
+
103
+})

+ 1 - 0
pages/index/list.json

@@ -0,0 +1 @@
1
+{}

+ 32 - 0
pages/index/list.wxml

@@ -0,0 +1,32 @@
1
+<view class="container FlexColumn" style="min-height:{{Containnerheight}}rpx;">
2
+
3
+  <view class="ViewContainerTitle1 Width100 FlexRow">
4
+    <view class="Left FlexRow">
5
+      题卡
6
+    </view>
7
+    <view></view>
8
+  </view>
9
+  <view class="ViewContainerContent2 Width100 FlexRow" wx:for="{{QuestionTypeList}}" wx:key="index" bindtap="gotoPrint" data-id="{{item.ID}}">
10
+    <view class="ViewContainerContent2_1 Left FlexColumn">
11
+      <view class="FlexRow">
12
+        <image class="ListIcon" src="{{FileUrl}}images/QuestionLibrary/QuestionTypesIcon1.png?2"  />
13
+        <view class="Left20">{{item.Name}}</view>
14
+        <view class="Left20 difficulty">{{item.DifficultyName}}</view>
15
+      </view>
16
+      <view class="ExampleContainer FlexRow">
17
+        <view class="letterSpacing">{{item.Example[0]}}</view>
18
+        <image class="XieGang" src="{{FileUrl}}images/xiegang.png" />
19
+        <view class="letterSpacing">{{item.Example[1]}}</view>
20
+        <image class="XieGang" src="{{FileUrl}}images/xiegang.png" wx:if="{{item.Example[2]}}" />
21
+        <view class="letterSpacing">{{item.Example[2]}}</view>
22
+      </view>
23
+    </view>
24
+    <view class="Right FlexRow">
25
+      
26
+      <image class="PrintIcon" src="../../images/print.png"  />
27
+        
28
+    </view>
29
+  </view>
30
+  <view class="footerHeight"></view>
31
+
32
+</view>

+ 59 - 0
pages/index/list.wxss

@@ -0,0 +1,59 @@
1
+
2
+.ViewContainerTitle1 {
3
+  background-color: #f0f0f0;
4
+  font-size: 28rpx;
5
+  font-weight: 500;
6
+  height: 100rpx;
7
+  justify-content: space-between;
8
+}
9
+
10
+.ViewContainerContent2 {
11
+  height: 132rpx;
12
+  background-color: #fff;
13
+  justify-content: space-between;
14
+  border-bottom: 1rpx solid #f0f0f0;
15
+  font-size: 30rpx;
16
+}
17
+
18
+.ViewContainerContent2_1{
19
+  justify-content: flex-start;
20
+  align-items: flex-start;
21
+}
22
+
23
+.ListIcon {
24
+  width: 36rpx;
25
+  height: 30rpx;
26
+}
27
+
28
+.Left20{
29
+  margin-left: 20rpx;
30
+}
31
+
32
+.XieGang {
33
+  margin: 0 10rpx 0 10rpx;
34
+  width:14rpx;
35
+  height:18rpx;
36
+}
37
+
38
+.ExampleContainer {
39
+  margin: 5rpx 0 0 60rpx;
40
+  font-size: 24rpx;
41
+  font-style: italic;
42
+  font-weight: 200;
43
+  justify-content: flex-start;
44
+}
45
+
46
+.letterSpacing {
47
+  letter-spacing: 6rpx;
48
+}
49
+
50
+.difficulty{
51
+  font-size:22rpx;
52
+  color:#9B9B9B;
53
+
54
+}
55
+
56
+.PrintIcon{
57
+  width:72rpx;
58
+  height:54rpx;
59
+}

+ 17 - 0
utils/cryptojs.js

@@ -0,0 +1,17 @@
1
+var Crypto = exports.Crypto = require('./lib/Crypto').Crypto;
2
+
3
+[ 'CryptoMath'
4
+, 'BlockModes'
5
+, 'DES'
6
+, 'AES'
7
+, 'HMAC'
8
+, 'MARC4'
9
+, 'MD5'
10
+, 'PBKDF2'
11
+, 'PBKDF2Async'
12
+, 'Rabbit'
13
+, 'SHA1'
14
+, 'SHA256'
15
+].forEach( function (path) {
16
+	require('./lib/' + path);
17
+});

+ 402 - 0
utils/lib/AES.js

@@ -0,0 +1,402 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8;
9
+
10
+// Precomputed SBOX
11
+var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
12
+             0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
13
+             0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
14
+             0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
15
+             0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
16
+             0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
17
+             0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
18
+             0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
19
+             0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
20
+             0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
21
+             0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
22
+             0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
23
+             0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
24
+             0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
25
+             0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
26
+             0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
27
+             0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
28
+             0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
29
+             0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
30
+             0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
31
+             0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
32
+             0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
33
+             0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
34
+             0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
35
+             0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
36
+             0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
37
+             0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
38
+             0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
39
+             0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
40
+             0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
41
+             0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
42
+             0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ];
43
+
44
+// Compute inverse SBOX lookup table
45
+for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i;
46
+
47
+// Compute mulitplication in GF(2^8) lookup tables
48
+var MULT2 = [],
49
+    MULT3 = [],
50
+    MULT9 = [],
51
+    MULTB = [],
52
+    MULTD = [],
53
+    MULTE = [];
54
+
55
+function xtime(a, b) {
56
+	for (var result = 0, i = 0; i < 8; i++) {
57
+		if (b & 1) result ^= a;
58
+		var hiBitSet = a & 0x80;
59
+		a = (a << 1) & 0xFF;
60
+		if (hiBitSet) a ^= 0x1b;
61
+		b >>>= 1;
62
+	}
63
+	return result;
64
+}
65
+
66
+for (var i = 0; i < 256; i++) {
67
+	MULT2[i] = xtime(i,2);
68
+	MULT3[i] = xtime(i,3);
69
+	MULT9[i] = xtime(i,9);
70
+	MULTB[i] = xtime(i,0xB);
71
+	MULTD[i] = xtime(i,0xD);
72
+	MULTE[i] = xtime(i,0xE);
73
+}
74
+
75
+// Precomputed RCon lookup
76
+var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
77
+
78
+// Inner state
79
+var state = [[], [], [], []],
80
+    keylength,
81
+    nrounds,
82
+    keyschedule;
83
+
84
+var AES = C.AES = {
85
+
86
+	/**
87
+	 * Public API
88
+	 */
89
+
90
+	encrypt: function (message, password, options) {
91
+
92
+		options = options || {};
93
+
94
+		// Determine mode
95
+		var mode = options.mode || new C.mode.OFB;
96
+
97
+		// Allow mode to override options
98
+		if (mode.fixOptions) mode.fixOptions(options);
99
+
100
+		var
101
+
102
+			// Convert to bytes if message is a string
103
+			m = (
104
+				message.constructor == String ?
105
+				UTF8.stringToBytes(message) :
106
+				message
107
+			),
108
+
109
+			// Generate random IV
110
+			iv = options.iv || util.randomBytes(AES._blocksize * 4),
111
+
112
+			// Generate key
113
+			k = (
114
+				password.constructor == String ?
115
+				// Derive key from passphrase
116
+				C.PBKDF2(password, iv, 32, { asBytes: true }) :
117
+				// else, assume byte array representing cryptographic key
118
+				password
119
+			);
120
+
121
+		// Encrypt
122
+		AES._init(k);
123
+		mode.encrypt(AES, m, iv);
124
+
125
+		// Return ciphertext
126
+		m = options.iv ? m : iv.concat(m);
127
+		return (options && options.asBytes) ? m : util.bytesToBase64(m);
128
+
129
+	},
130
+
131
+	decrypt: function (ciphertext, password, options) {
132
+
133
+		options = options || {};
134
+
135
+		// Determine mode
136
+		var mode = options.mode || new C.mode.OFB;
137
+
138
+		// Allow mode to override options
139
+		if (mode.fixOptions) mode.fixOptions(options);
140
+
141
+		var
142
+
143
+			// Convert to bytes if ciphertext is a string
144
+			c = (
145
+				ciphertext.constructor == String ?
146
+				util.base64ToBytes(ciphertext):
147
+			    ciphertext
148
+			),
149
+
150
+			// Separate IV and message
151
+			iv = options.iv || c.splice(0, AES._blocksize * 4),
152
+
153
+			// Generate key
154
+			k = (
155
+				password.constructor == String ?
156
+				// Derive key from passphrase
157
+				C.PBKDF2(password, iv, 32, { asBytes: true }) :
158
+				// else, assume byte array representing cryptographic key
159
+				password
160
+			);
161
+
162
+		// Decrypt
163
+		AES._init(k);
164
+		mode.decrypt(AES, c, iv);
165
+
166
+		// Return plaintext
167
+		return (options && options.asBytes) ? c : UTF8.bytesToString(c);
168
+
169
+	},
170
+
171
+
172
+	/**
173
+	 * Package private methods and properties
174
+	 */
175
+
176
+	_blocksize: 4,
177
+
178
+	_encryptblock: function (m, offset) {
179
+
180
+		// Set input
181
+		for (var row = 0; row < AES._blocksize; row++) {
182
+			for (var col = 0; col < 4; col++)
183
+				state[row][col] = m[offset + col * 4 + row];
184
+		}
185
+
186
+		// Add round key
187
+		for (var row = 0; row < 4; row++) {
188
+			for (var col = 0; col < 4; col++)
189
+				state[row][col] ^= keyschedule[col][row];
190
+		}
191
+
192
+		for (var round = 1; round < nrounds; round++) {
193
+
194
+			// Sub bytes
195
+			for (var row = 0; row < 4; row++) {
196
+				for (var col = 0; col < 4; col++)
197
+					state[row][col] = SBOX[state[row][col]];
198
+			}
199
+
200
+			// Shift rows
201
+			state[1].push(state[1].shift());
202
+			state[2].push(state[2].shift());
203
+			state[2].push(state[2].shift());
204
+			state[3].unshift(state[3].pop());
205
+
206
+			// Mix columns
207
+			for (var col = 0; col < 4; col++) {
208
+
209
+				var s0 = state[0][col],
210
+				    s1 = state[1][col],
211
+				    s2 = state[2][col],
212
+				    s3 = state[3][col];
213
+
214
+				state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3;
215
+				state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3;
216
+				state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3];
217
+				state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3];
218
+
219
+			}
220
+
221
+			// Add round key
222
+			for (var row = 0; row < 4; row++) {
223
+				for (var col = 0; col < 4; col++)
224
+					state[row][col] ^= keyschedule[round * 4 + col][row];
225
+			}
226
+
227
+		}
228
+
229
+		// Sub bytes
230
+		for (var row = 0; row < 4; row++) {
231
+			for (var col = 0; col < 4; col++)
232
+				state[row][col] = SBOX[state[row][col]];
233
+		}
234
+
235
+		// Shift rows
236
+		state[1].push(state[1].shift());
237
+		state[2].push(state[2].shift());
238
+		state[2].push(state[2].shift());
239
+		state[3].unshift(state[3].pop());
240
+
241
+		// Add round key
242
+		for (var row = 0; row < 4; row++) {
243
+			for (var col = 0; col < 4; col++)
244
+				state[row][col] ^= keyschedule[nrounds * 4 + col][row];
245
+		}
246
+
247
+		// Set output
248
+		for (var row = 0; row < AES._blocksize; row++) {
249
+			for (var col = 0; col < 4; col++)
250
+				m[offset + col * 4 + row] = state[row][col];
251
+		}
252
+
253
+	},
254
+
255
+	_decryptblock: function (c, offset) {
256
+
257
+		// Set input
258
+		for (var row = 0; row < AES._blocksize; row++) {
259
+			for (var col = 0; col < 4; col++)
260
+				state[row][col] = c[offset + col * 4 + row];
261
+		}
262
+
263
+		// Add round key
264
+		for (var row = 0; row < 4; row++) {
265
+			for (var col = 0; col < 4; col++)
266
+				state[row][col] ^= keyschedule[nrounds * 4 + col][row];
267
+		}
268
+
269
+		for (var round = 1; round < nrounds; round++) {
270
+
271
+			// Inv shift rows
272
+			state[1].unshift(state[1].pop());
273
+			state[2].push(state[2].shift());
274
+			state[2].push(state[2].shift());
275
+			state[3].push(state[3].shift());
276
+
277
+			// Inv sub bytes
278
+			for (var row = 0; row < 4; row++) {
279
+				for (var col = 0; col < 4; col++)
280
+					state[row][col] = INVSBOX[state[row][col]];
281
+			}
282
+
283
+			// Add round key
284
+			for (var row = 0; row < 4; row++) {
285
+				for (var col = 0; col < 4; col++)
286
+					state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row];
287
+			}
288
+
289
+			// Inv mix columns
290
+			for (var col = 0; col < 4; col++) {
291
+
292
+				var s0 = state[0][col],
293
+				    s1 = state[1][col],
294
+				    s2 = state[2][col],
295
+				    s3 = state[3][col];
296
+
297
+				state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3];
298
+				state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3];
299
+				state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3];
300
+				state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3];
301
+
302
+			}
303
+
304
+		}
305
+
306
+		// Inv shift rows
307
+		state[1].unshift(state[1].pop());
308
+		state[2].push(state[2].shift());
309
+		state[2].push(state[2].shift());
310
+		state[3].push(state[3].shift());
311
+
312
+		// Inv sub bytes
313
+		for (var row = 0; row < 4; row++) {
314
+			for (var col = 0; col < 4; col++)
315
+				state[row][col] = INVSBOX[state[row][col]];
316
+		}
317
+
318
+		// Add round key
319
+		for (var row = 0; row < 4; row++) {
320
+			for (var col = 0; col < 4; col++)
321
+				state[row][col] ^= keyschedule[col][row];
322
+		}
323
+
324
+		// Set output
325
+		for (var row = 0; row < AES._blocksize; row++) {
326
+			for (var col = 0; col < 4; col++)
327
+				c[offset + col * 4 + row] = state[row][col];
328
+		}
329
+
330
+	},
331
+
332
+
333
+	/**
334
+	 * Private methods
335
+	 */
336
+
337
+	_init: function (k) {
338
+		keylength = k.length / 4;
339
+		nrounds = keylength + 6;
340
+		AES._keyexpansion(k);
341
+	},
342
+
343
+	// Generate a key schedule
344
+	_keyexpansion: function (k) {
345
+
346
+		keyschedule = [];
347
+
348
+		for (var row = 0; row < keylength; row++) {
349
+			keyschedule[row] = [
350
+				k[row * 4],
351
+				k[row * 4 + 1],
352
+				k[row * 4 + 2],
353
+				k[row * 4 + 3]
354
+			];
355
+		}
356
+
357
+		for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) {
358
+
359
+			var temp = [
360
+				keyschedule[row - 1][0],
361
+				keyschedule[row - 1][1],
362
+				keyschedule[row - 1][2],
363
+				keyschedule[row - 1][3]
364
+			];
365
+
366
+			if (row % keylength == 0) {
367
+
368
+				// Rot word
369
+				temp.push(temp.shift());
370
+
371
+				// Sub word
372
+				temp[0] = SBOX[temp[0]];
373
+				temp[1] = SBOX[temp[1]];
374
+				temp[2] = SBOX[temp[2]];
375
+				temp[3] = SBOX[temp[3]];
376
+
377
+				temp[0] ^= RCON[row / keylength];
378
+
379
+			} else if (keylength > 6 && row % keylength == 4) {
380
+
381
+				// Sub word
382
+				temp[0] = SBOX[temp[0]];
383
+				temp[1] = SBOX[temp[1]];
384
+				temp[2] = SBOX[temp[2]];
385
+				temp[3] = SBOX[temp[3]];
386
+
387
+			}
388
+
389
+			keyschedule[row] = [
390
+				keyschedule[row - keylength][0] ^ temp[0],
391
+				keyschedule[row - keylength][1] ^ temp[1],
392
+				keyschedule[row - keylength][2] ^ temp[2],
393
+				keyschedule[row - keylength][3] ^ temp[3]
394
+			];
395
+
396
+		}
397
+
398
+	}
399
+
400
+};
401
+
402
+})();

+ 378 - 0
utils/lib/BlockModes.js

@@ -0,0 +1,378 @@
1
+/*!
2
+ * Crypto-JS contribution from Simon Greatrix
3
+ */
4
+
5
+(function(){
6
+
7
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
8
+
9
+// Create pad namespace
10
+var C_pad = C.pad = {};
11
+
12
+// Calculate the number of padding bytes required.
13
+function _requiredPadding(cipher, message) {
14
+    var blockSizeInBytes = cipher._blocksize * 4;
15
+    var reqd = blockSizeInBytes - message.length % blockSizeInBytes;
16
+    return reqd;
17
+};
18
+
19
+// Remove padding when the final byte gives the number of padding bytes.
20
+var _unpadLength = function (message) {
21
+        var pad = message.pop();
22
+        for (var i = 1; i < pad; i++) {
23
+            message.pop();
24
+        }
25
+    };
26
+
27
+// No-operation padding, used for stream ciphers
28
+C_pad.NoPadding = {
29
+        pad : function (cipher,message) {},
30
+        unpad : function (message) {}
31
+    };
32
+
33
+// Zero Padding.
34
+//
35
+// If the message is not an exact number of blocks, the final block is
36
+// completed with 0x00 bytes. There is no unpadding.
37
+C_pad.ZeroPadding = {
38
+    pad : function (cipher, message) {
39
+        var blockSizeInBytes = cipher._blocksize * 4;
40
+        var reqd = message.length % blockSizeInBytes;
41
+        if( reqd!=0 ) {
42
+            for(reqd = blockSizeInBytes - reqd; reqd>0; reqd--) {
43
+                message.push(0x00);
44
+            }
45
+        }
46
+    },
47
+
48
+    unpad : function (message) {}
49
+};
50
+
51
+// ISO/IEC 7816-4 padding.
52
+//
53
+// Pads the plain text with an 0x80 byte followed by as many 0x00
54
+// bytes are required to complete the block.
55
+C_pad.iso7816 = {
56
+    pad : function (cipher, message) {
57
+        var reqd = _requiredPadding(cipher, message);
58
+        message.push(0x80);
59
+        for (; reqd > 1; reqd--) {
60
+            message.push(0x00);
61
+        }
62
+    },
63
+
64
+    unpad : function (message) {
65
+        while (message.pop() != 0x80) {}
66
+    }
67
+};
68
+
69
+// ANSI X.923 padding
70
+//
71
+// The final block is padded with zeros except for the last byte of the
72
+// last block which contains the number of padding bytes.
73
+C_pad.ansix923 = {
74
+    pad : function (cipher, message) {
75
+        var reqd = _requiredPadding(cipher, message);
76
+        for (var i = 1; i < reqd; i++) {
77
+            message.push(0x00);
78
+        }
79
+        message.push(reqd);
80
+    },
81
+
82
+    unpad : _unpadLength
83
+};
84
+
85
+// ISO 10126
86
+//
87
+// The final block is padded with random bytes except for the last
88
+// byte of the last block which contains the number of padding bytes.
89
+C_pad.iso10126 = {
90
+    pad : function (cipher, message) {
91
+        var reqd = _requiredPadding(cipher, message);
92
+        for (var i = 1; i < reqd; i++) {
93
+            message.push(Math.floor(Math.random() * 256));
94
+        }
95
+        message.push(reqd);
96
+    },
97
+
98
+    unpad : _unpadLength
99
+};
100
+
101
+// PKCS7 padding
102
+//
103
+// PKCS7 is described in RFC 5652. Padding is in whole bytes. The
104
+// value of each added byte is the number of bytes that are added,
105
+// i.e. N bytes, each of value N are added.
106
+C_pad.pkcs7 = {
107
+    pad : function (cipher, message) {
108
+        var reqd = _requiredPadding(cipher, message);
109
+        for (var i = 0; i < reqd; i++) {
110
+            message.push(reqd);
111
+        }
112
+    },
113
+
114
+    unpad : _unpadLength
115
+};
116
+
117
+// Create mode namespace
118
+var C_mode = C.mode = {};
119
+
120
+/**
121
+ * Mode base "class".
122
+ */
123
+var Mode = C_mode.Mode = function (padding) {
124
+    if (padding) {
125
+        this._padding = padding;
126
+    }
127
+};
128
+
129
+Mode.prototype = {
130
+    encrypt: function (cipher, m, iv) {
131
+        this._padding.pad(cipher, m);
132
+        this._doEncrypt(cipher, m, iv);
133
+    },
134
+
135
+    decrypt: function (cipher, m, iv) {
136
+        this._doDecrypt(cipher, m, iv);
137
+        this._padding.unpad(m);
138
+    },
139
+
140
+    // Default padding
141
+    _padding: C_pad.iso7816
142
+};
143
+
144
+
145
+/**
146
+ * Electronic Code Book mode.
147
+ * 
148
+ * ECB applies the cipher directly against each block of the input.
149
+ * 
150
+ * ECB does not require an initialization vector.
151
+ */
152
+var ECB = C_mode.ECB = function () {
153
+    // Call parent constructor
154
+    Mode.apply(this, arguments);
155
+};
156
+
157
+// Inherit from Mode
158
+var ECB_prototype = ECB.prototype = new Mode;
159
+
160
+// Concrete steps for Mode template
161
+ECB_prototype._doEncrypt = function (cipher, m, iv) {
162
+    var blockSizeInBytes = cipher._blocksize * 4;
163
+    // Encrypt each block
164
+    for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
165
+        cipher._encryptblock(m, offset);
166
+    }
167
+};
168
+ECB_prototype._doDecrypt = function (cipher, c, iv) {
169
+    var blockSizeInBytes = cipher._blocksize * 4;
170
+    // Decrypt each block
171
+    for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
172
+        cipher._decryptblock(c, offset);
173
+    }
174
+};
175
+
176
+// ECB never uses an IV
177
+ECB_prototype.fixOptions = function (options) {
178
+    options.iv = [];
179
+};
180
+
181
+
182
+/**
183
+ * Cipher block chaining
184
+ * 
185
+ * The first block is XORed with the IV. Subsequent blocks are XOR with the
186
+ * previous cipher output.
187
+ */
188
+var CBC = C_mode.CBC = function () {
189
+    // Call parent constructor
190
+    Mode.apply(this, arguments);
191
+};
192
+
193
+// Inherit from Mode
194
+var CBC_prototype = CBC.prototype = new Mode;
195
+
196
+// Concrete steps for Mode template
197
+CBC_prototype._doEncrypt = function (cipher, m, iv) {
198
+    var blockSizeInBytes = cipher._blocksize * 4;
199
+
200
+    // Encrypt each block
201
+    for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
202
+        if (offset == 0) {
203
+            // XOR first block using IV
204
+            for (var i = 0; i < blockSizeInBytes; i++)
205
+            m[i] ^= iv[i];
206
+        } else {
207
+            // XOR this block using previous crypted block
208
+            for (var i = 0; i < blockSizeInBytes; i++)
209
+            m[offset + i] ^= m[offset + i - blockSizeInBytes];
210
+        }
211
+        // Encrypt block
212
+        cipher._encryptblock(m, offset);
213
+    }
214
+};
215
+CBC_prototype._doDecrypt = function (cipher, c, iv) {
216
+    var blockSizeInBytes = cipher._blocksize * 4;
217
+
218
+    // At the start, the previously crypted block is the IV
219
+    var prevCryptedBlock = iv;
220
+
221
+    // Decrypt each block
222
+    for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
223
+        // Save this crypted block
224
+        var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes);
225
+        // Decrypt block
226
+        cipher._decryptblock(c, offset);
227
+        // XOR decrypted block using previous crypted block
228
+        for (var i = 0; i < blockSizeInBytes; i++) {
229
+            c[offset + i] ^= prevCryptedBlock[i];
230
+        }
231
+        prevCryptedBlock = thisCryptedBlock;
232
+    }
233
+};
234
+
235
+
236
+/**
237
+ * Cipher feed back
238
+ * 
239
+ * The cipher output is XORed with the plain text to produce the cipher output,
240
+ * which is then fed back into the cipher to produce a bit pattern to XOR the
241
+ * next block with.
242
+ * 
243
+ * This is a stream cipher mode and does not require padding.
244
+ */
245
+var CFB = C_mode.CFB = function () {
246
+    // Call parent constructor
247
+    Mode.apply(this, arguments);
248
+};
249
+
250
+// Inherit from Mode
251
+var CFB_prototype = CFB.prototype = new Mode;
252
+
253
+// Override padding
254
+CFB_prototype._padding = C_pad.NoPadding;
255
+
256
+// Concrete steps for Mode template
257
+CFB_prototype._doEncrypt = function (cipher, m, iv) {
258
+    var blockSizeInBytes = cipher._blocksize * 4,
259
+        keystream = iv.slice(0);
260
+
261
+    // Encrypt each byte
262
+    for (var i = 0; i < m.length; i++) {
263
+
264
+        var j = i % blockSizeInBytes;
265
+        if (j == 0) cipher._encryptblock(keystream, 0);
266
+
267
+        m[i] ^= keystream[j];
268
+        keystream[j] = m[i];
269
+    }
270
+};
271
+CFB_prototype._doDecrypt = function (cipher, c, iv) {
272
+    var blockSizeInBytes = cipher._blocksize * 4,
273
+        keystream = iv.slice(0);
274
+
275
+    // Encrypt each byte
276
+    for (var i = 0; i < c.length; i++) {
277
+
278
+        var j = i % blockSizeInBytes;
279
+        if (j == 0) cipher._encryptblock(keystream, 0);
280
+
281
+        var b = c[i];
282
+        c[i] ^= keystream[j];
283
+        keystream[j] = b;
284
+    }
285
+};
286
+
287
+
288
+/**
289
+ * Output feed back
290
+ * 
291
+ * The cipher repeatedly encrypts its own output. The output is XORed with the
292
+ * plain text to produce the cipher text.
293
+ * 
294
+ * This is a stream cipher mode and does not require padding.
295
+ */
296
+var OFB = C_mode.OFB = function () {
297
+    // Call parent constructor
298
+    Mode.apply(this, arguments);
299
+};
300
+
301
+// Inherit from Mode
302
+var OFB_prototype = OFB.prototype = new Mode;
303
+
304
+// Override padding
305
+OFB_prototype._padding = C_pad.NoPadding;
306
+
307
+// Concrete steps for Mode template
308
+OFB_prototype._doEncrypt = function (cipher, m, iv) {
309
+
310
+    var blockSizeInBytes = cipher._blocksize * 4,
311
+        keystream = iv.slice(0);
312
+
313
+    // Encrypt each byte
314
+    for (var i = 0; i < m.length; i++) {
315
+
316
+        // Generate keystream
317
+        if (i % blockSizeInBytes == 0)
318
+            cipher._encryptblock(keystream, 0);
319
+
320
+        // Encrypt byte
321
+        m[i] ^= keystream[i % blockSizeInBytes];
322
+
323
+    }
324
+};
325
+OFB_prototype._doDecrypt = OFB_prototype._doEncrypt;
326
+
327
+/**
328
+ * Counter
329
+ * @author Gergely Risko
330
+ *
331
+ * After every block the last 4 bytes of the IV is increased by one
332
+ * with carry and that IV is used for the next block.
333
+ *
334
+ * This is a stream cipher mode and does not require padding.
335
+ */
336
+var CTR = C_mode.CTR = function () {
337
+    // Call parent constructor
338
+    Mode.apply(this, arguments);
339
+};
340
+
341
+// Inherit from Mode
342
+var CTR_prototype = CTR.prototype = new Mode;
343
+
344
+// Override padding
345
+CTR_prototype._padding = C_pad.NoPadding;
346
+
347
+CTR_prototype._doEncrypt = function (cipher, m, iv) {
348
+    var blockSizeInBytes = cipher._blocksize * 4;
349
+    var counter = iv.slice(0);
350
+
351
+    for (var i = 0; i < m.length;) {
352
+        // do not lose iv
353
+        var keystream = counter.slice(0);
354
+
355
+        // Generate keystream for next block
356
+        cipher._encryptblock(keystream, 0);
357
+
358
+        // XOR keystream with block
359
+        for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) {
360
+            m[i] ^= keystream[j];
361
+        }
362
+
363
+        // Increase counter
364
+        if(++(counter[blockSizeInBytes-1]) == 256) {
365
+            counter[blockSizeInBytes-1] = 0;
366
+            if(++(counter[blockSizeInBytes-2]) == 256) {
367
+                counter[blockSizeInBytes-2] = 0;
368
+                if(++(counter[blockSizeInBytes-3]) == 256) {
369
+                    counter[blockSizeInBytes-3] = 0;
370
+                    ++(counter[blockSizeInBytes-4]);
371
+                }
372
+            }
373
+        }
374
+    }
375
+};
376
+CTR_prototype._doDecrypt = CTR_prototype._doEncrypt;
377
+
378
+})();

+ 155 - 0
utils/lib/Crypto.js

@@ -0,0 +1,155 @@
1
+if (typeof Crypto == "undefined" || ! Crypto.util)
2
+{
3
+(function(){
4
+
5
+var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
6
+
7
+// Global Crypto object
8
+// with browser window or with node module
9
+var Crypto = (typeof window === 'undefined') ? exports.Crypto = {} : window.Crypto = {}; 
10
+
11
+// Crypto utilities
12
+var util = Crypto.util = {
13
+
14
+	// Bit-wise rotate left
15
+	rotl: function (n, b) {
16
+		return (n << b) | (n >>> (32 - b));
17
+	},
18
+
19
+	// Bit-wise rotate right
20
+	rotr: function (n, b) {
21
+		return (n << (32 - b)) | (n >>> b);
22
+	},
23
+
24
+	// Swap big-endian to little-endian and vice versa
25
+	endian: function (n) {
26
+
27
+		// If number given, swap endian
28
+		if (n.constructor == Number) {
29
+			return util.rotl(n,  8) & 0x00FF00FF |
30
+			       util.rotl(n, 24) & 0xFF00FF00;
31
+		}
32
+
33
+		// Else, assume array and swap all items
34
+		for (var i = 0; i < n.length; i++)
35
+			n[i] = util.endian(n[i]);
36
+		return n;
37
+
38
+	},
39
+
40
+	// Generate an array of any length of random bytes
41
+	randomBytes: function (n) {
42
+		for (var bytes = []; n > 0; n--)
43
+			bytes.push(Math.floor(Math.random() * 256));
44
+		return bytes;
45
+	},
46
+
47
+	// Convert a byte array to big-endian 32-bit words
48
+	bytesToWords: function (bytes) {
49
+		for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
50
+			words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32);
51
+		return words;
52
+	},
53
+
54
+	// Convert big-endian 32-bit words to a byte array
55
+	wordsToBytes: function (words) {
56
+		for (var bytes = [], b = 0; b < words.length * 32; b += 8)
57
+			bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
58
+		return bytes;
59
+	},
60
+
61
+	// Convert a byte array to a hex string
62
+	bytesToHex: function (bytes) {
63
+		for (var hex = [], i = 0; i < bytes.length; i++) {
64
+			hex.push((bytes[i] >>> 4).toString(16));
65
+			hex.push((bytes[i] & 0xF).toString(16));
66
+		}
67
+		return hex.join("");
68
+	},
69
+
70
+	// Convert a hex string to a byte array
71
+	hexToBytes: function (hex) {
72
+		for (var bytes = [], c = 0; c < hex.length; c += 2)
73
+			bytes.push(parseInt(hex.substr(c, 2), 16));
74
+		return bytes;
75
+	},
76
+
77
+	// Convert a byte array to a base-64 string
78
+	bytesToBase64: function (bytes) {
79
+
80
+		// Use browser-native function if it exists
81
+		if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes));
82
+
83
+		for(var base64 = [], i = 0; i < bytes.length; i += 3) {
84
+			var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
85
+			for (var j = 0; j < 4; j++) {
86
+				if (i * 8 + j * 6 <= bytes.length * 8)
87
+					base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
88
+				else base64.push("=");
89
+			}
90
+		}
91
+
92
+		return base64.join("");
93
+
94
+	},
95
+
96
+	// Convert a base-64 string to a byte array
97
+	base64ToBytes: function (base64) {
98
+
99
+		// Use browser-native function if it exists
100
+		if (typeof atob == "function") return Binary.stringToBytes(atob(base64));
101
+
102
+		// Remove non-base-64 characters
103
+		base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
104
+
105
+		for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) {
106
+			if (imod4 == 0) continue;
107
+			bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) |
108
+			           (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
109
+		}
110
+
111
+		return bytes;
112
+
113
+	}
114
+
115
+};
116
+
117
+// Crypto character encodings
118
+var charenc = Crypto.charenc = {};
119
+
120
+// UTF-8 encoding
121
+var UTF8 = charenc.UTF8 = {
122
+
123
+	// Convert a string to a byte array
124
+	stringToBytes: function (str) {
125
+		return Binary.stringToBytes(unescape(encodeURIComponent(str)));
126
+	},
127
+
128
+	// Convert a byte array to a string
129
+	bytesToString: function (bytes) {
130
+		return decodeURIComponent(escape(Binary.bytesToString(bytes)));
131
+	}
132
+
133
+};
134
+
135
+// Binary encoding
136
+var Binary = charenc.Binary = {
137
+
138
+	// Convert a string to a byte array
139
+	stringToBytes: function (str) {
140
+		for (var bytes = [], i = 0; i < str.length; i++)
141
+			bytes.push(str.charCodeAt(i) & 0xFF);
142
+		return bytes;
143
+	},
144
+
145
+	// Convert a byte array to a string
146
+	bytesToString: function (bytes) {
147
+		for (var str = [], i = 0; i < bytes.length; i++)
148
+			str.push(String.fromCharCode(bytes[i]));
149
+		return str.join("");
150
+	}
151
+
152
+};
153
+
154
+})();
155
+}

+ 37 - 0
utils/lib/CryptoMath.js

@@ -0,0 +1,37 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcut
6
+var util = C.util;
7
+
8
+// Convert n to unsigned 32-bit integer
9
+util.u32 = function (n) {
10
+	return n >>> 0;
11
+};
12
+
13
+// Unsigned 32-bit addition
14
+util.add = function () {
15
+	var result = this.u32(arguments[0]);
16
+	for (var i = 1; i < arguments.length; i++)
17
+		result = this.u32(result + this.u32(arguments[i]));
18
+	return result;
19
+};
20
+
21
+// Unsigned 32-bit multiplication
22
+util.mult = function (m, n) {
23
+	return this.add((n & 0xFFFF0000) * m,
24
+			(n & 0x0000FFFF) * m);
25
+};
26
+
27
+// Unsigned 32-bit greater than (>) comparison
28
+util.gt = function (m, n) {
29
+	return this.u32(m) > this.u32(n);
30
+};
31
+
32
+// Unsigned 32-bit less than (<) comparison
33
+util.lt = function (m, n) {
34
+	return this.u32(m) < this.u32(n);
35
+};
36
+
37
+})();

File diff suppressed because it is too large
+ 1003 - 0
utils/lib/DES.js


+ 38 - 0
utils/lib/HMAC.js

@@ -0,0 +1,38 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8,
9
+    Binary = charenc.Binary;
10
+
11
+C.HMAC = function (hasher, message, key, options) {
12
+
13
+	// Convert to byte arrays
14
+	if (message.constructor == String) message = UTF8.stringToBytes(message);
15
+	if (key.constructor == String) key = UTF8.stringToBytes(key);
16
+	/* else, assume byte arrays already */
17
+
18
+	// Allow arbitrary length keys
19
+	if (key.length > hasher._blocksize * 4)
20
+		key = hasher(key, { asBytes: true });
21
+
22
+	// XOR keys with pad constants
23
+	var okey = key.slice(0),
24
+	    ikey = key.slice(0);
25
+	for (var i = 0; i < hasher._blocksize * 4; i++) {
26
+		okey[i] ^= 0x5C;
27
+		ikey[i] ^= 0x36;
28
+	}
29
+
30
+	var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true });
31
+
32
+	return options && options.asBytes ? hmacbytes :
33
+	       options && options.asString ? Binary.bytesToString(hmacbytes) :
34
+	       util.bytesToHex(hmacbytes);
35
+
36
+};
37
+
38
+})();

+ 117 - 0
utils/lib/MARC4.js

@@ -0,0 +1,117 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8,
9
+    Binary = charenc.Binary;
10
+
11
+var MARC4 = C.MARC4 = {
12
+
13
+	/**
14
+	 * Public API
15
+	 */
16
+
17
+	encrypt: function (message, password) {
18
+
19
+		var
20
+
21
+		    // Convert to bytes
22
+		    m = UTF8.stringToBytes(message),
23
+
24
+		    // Generate random IV
25
+		    iv = util.randomBytes(16),
26
+
27
+		    // Generate key
28
+		    k = password.constructor == String ?
29
+		        // Derive key from passphrase
30
+		        C.PBKDF2(password, iv, 32, { asBytes: true }) :
31
+		        // else, assume byte array representing cryptographic key
32
+		        password;
33
+
34
+		// Encrypt
35
+		MARC4._marc4(m, k, 1536);
36
+
37
+		// Return ciphertext
38
+		return util.bytesToBase64(iv.concat(m));
39
+
40
+	},
41
+
42
+	decrypt: function (ciphertext, password) {
43
+
44
+		var
45
+
46
+		    // Convert to bytes
47
+		    c = util.base64ToBytes(ciphertext),
48
+
49
+		    // Separate IV and message
50
+		    iv = c.splice(0, 16),
51
+
52
+		    // Generate key
53
+		    k = password.constructor == String ?
54
+		        // Derive key from passphrase
55
+		        C.PBKDF2(password, iv, 32, { asBytes: true }) :
56
+		        // else, assume byte array representing cryptographic key
57
+		        password;
58
+
59
+		// Decrypt
60
+		MARC4._marc4(c, k, 1536);
61
+
62
+		// Return plaintext
63
+		return UTF8.bytesToString(c);
64
+
65
+	},
66
+
67
+
68
+	/**
69
+	 * Internal methods
70
+	 */
71
+
72
+	// The core
73
+	_marc4: function (m, k, drop) {
74
+
75
+		// State variables
76
+		var i, j, s, temp;
77
+
78
+		// Key setup
79
+		for (i = 0, s = []; i < 256; i++) s[i] = i;
80
+		for (i = 0, j = 0;  i < 256; i++) {
81
+
82
+			j = (j + s[i] + k[i % k.length]) % 256;
83
+
84
+			// Swap
85
+			temp = s[i];
86
+			s[i] = s[j];
87
+			s[j] = temp;
88
+
89
+		}
90
+
91
+		// Clear counters
92
+		i = j = 0;
93
+
94
+		// Encryption
95
+		for (var k = -drop; k < m.length; k++) {
96
+
97
+			i = (i + 1) % 256;
98
+			j = (j + s[i]) % 256;
99
+
100
+			// Swap
101
+			temp = s[i];
102
+			s[i] = s[j];
103
+			s[j] = temp;
104
+
105
+			// Stop here if we're still dropping keystream
106
+			if (k < 0) continue;
107
+
108
+			// Encrypt
109
+			m[k] ^= s[(s[i] + s[j]) % 256];
110
+
111
+		}
112
+
113
+	}
114
+
115
+};
116
+
117
+})();

+ 158 - 0
utils/lib/MD5.js

@@ -0,0 +1,158 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8,
9
+    Binary = charenc.Binary;
10
+
11
+// Public API
12
+var MD5 = C.MD5 = function (message, options) {
13
+	var digestbytes = util.wordsToBytes(MD5._md5(message));
14
+	return options && options.asBytes ? digestbytes :
15
+	       options && options.asString ? Binary.bytesToString(digestbytes) :
16
+	       util.bytesToHex(digestbytes);
17
+};
18
+
19
+// The core
20
+MD5._md5 = function (message) {
21
+
22
+	// Convert to byte array
23
+	if (message.constructor == String) message = UTF8.stringToBytes(message);
24
+	/* else, assume byte array already */
25
+
26
+	var m = util.bytesToWords(message),
27
+	    l = message.length * 8,
28
+	    a =  1732584193,
29
+	    b = -271733879,
30
+	    c = -1732584194,
31
+	    d =  271733878;
32
+
33
+	// Swap endian
34
+	for (var i = 0; i < m.length; i++) {
35
+		m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
36
+		       ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
37
+	}
38
+
39
+	// Padding
40
+	m[l >>> 5] |= 0x80 << (l % 32);
41
+	m[(((l + 64) >>> 9) << 4) + 14] = l;
42
+
43
+	// Method shortcuts
44
+	var FF = MD5._ff,
45
+	    GG = MD5._gg,
46
+	    HH = MD5._hh,
47
+	    II = MD5._ii;
48
+
49
+	for (var i = 0; i < m.length; i += 16) {
50
+
51
+		var aa = a,
52
+		    bb = b,
53
+		    cc = c,
54
+		    dd = d;
55
+
56
+		a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
57
+		d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
58
+		c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
59
+		b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
60
+		a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
61
+		d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
62
+		c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
63
+		b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
64
+		a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
65
+		d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
66
+		c = FF(c, d, a, b, m[i+10], 17, -42063);
67
+		b = FF(b, c, d, a, m[i+11], 22, -1990404162);
68
+		a = FF(a, b, c, d, m[i+12],  7,  1804603682);
69
+		d = FF(d, a, b, c, m[i+13], 12, -40341101);
70
+		c = FF(c, d, a, b, m[i+14], 17, -1502002290);
71
+		b = FF(b, c, d, a, m[i+15], 22,  1236535329);
72
+
73
+		a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
74
+		d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
75
+		c = GG(c, d, a, b, m[i+11], 14,  643717713);
76
+		b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
77
+		a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
78
+		d = GG(d, a, b, c, m[i+10],  9,  38016083);
79
+		c = GG(c, d, a, b, m[i+15], 14, -660478335);
80
+		b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
81
+		a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
82
+		d = GG(d, a, b, c, m[i+14],  9, -1019803690);
83
+		c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
84
+		b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
85
+		a = GG(a, b, c, d, m[i+13],  5, -1444681467);
86
+		d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
87
+		c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
88
+		b = GG(b, c, d, a, m[i+12], 20, -1926607734);
89
+
90
+		a = HH(a, b, c, d, m[i+ 5],  4, -378558);
91
+		d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
92
+		c = HH(c, d, a, b, m[i+11], 16,  1839030562);
93
+		b = HH(b, c, d, a, m[i+14], 23, -35309556);
94
+		a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
95
+		d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
96
+		c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
97
+		b = HH(b, c, d, a, m[i+10], 23, -1094730640);
98
+		a = HH(a, b, c, d, m[i+13],  4,  681279174);
99
+		d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
100
+		c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
101
+		b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
102
+		a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
103
+		d = HH(d, a, b, c, m[i+12], 11, -421815835);
104
+		c = HH(c, d, a, b, m[i+15], 16,  530742520);
105
+		b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
106
+
107
+		a = II(a, b, c, d, m[i+ 0],  6, -198630844);
108
+		d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
109
+		c = II(c, d, a, b, m[i+14], 15, -1416354905);
110
+		b = II(b, c, d, a, m[i+ 5], 21, -57434055);
111
+		a = II(a, b, c, d, m[i+12],  6,  1700485571);
112
+		d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
113
+		c = II(c, d, a, b, m[i+10], 15, -1051523);
114
+		b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
115
+		a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
116
+		d = II(d, a, b, c, m[i+15], 10, -30611744);
117
+		c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
118
+		b = II(b, c, d, a, m[i+13], 21,  1309151649);
119
+		a = II(a, b, c, d, m[i+ 4],  6, -145523070);
120
+		d = II(d, a, b, c, m[i+11], 10, -1120210379);
121
+		c = II(c, d, a, b, m[i+ 2], 15,  718787259);
122
+		b = II(b, c, d, a, m[i+ 9], 21, -343485551);
123
+
124
+		a = (a + aa) >>> 0;
125
+		b = (b + bb) >>> 0;
126
+		c = (c + cc) >>> 0;
127
+		d = (d + dd) >>> 0;
128
+
129
+	}
130
+
131
+	return util.endian([a, b, c, d]);
132
+
133
+};
134
+
135
+// Auxiliary functions
136
+MD5._ff  = function (a, b, c, d, x, s, t) {
137
+	var n = a + (b & c | ~b & d) + (x >>> 0) + t;
138
+	return ((n << s) | (n >>> (32 - s))) + b;
139
+};
140
+MD5._gg  = function (a, b, c, d, x, s, t) {
141
+	var n = a + (b & d | c & ~d) + (x >>> 0) + t;
142
+	return ((n << s) | (n >>> (32 - s))) + b;
143
+};
144
+MD5._hh  = function (a, b, c, d, x, s, t) {
145
+	var n = a + (b ^ c ^ d) + (x >>> 0) + t;
146
+	return ((n << s) | (n >>> (32 - s))) + b;
147
+};
148
+MD5._ii  = function (a, b, c, d, x, s, t) {
149
+	var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
150
+	return ((n << s) | (n >>> (32 - s))) + b;
151
+};
152
+
153
+// Package private blocksize
154
+MD5._blocksize = 16;
155
+
156
+MD5._digestsize = 16;
157
+
158
+})();

+ 49 - 0
utils/lib/PBKDF2.js

@@ -0,0 +1,49 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8,
9
+    Binary = charenc.Binary;
10
+
11
+C.PBKDF2 = function (password, salt, keylen, options) {
12
+
13
+	// Convert to byte arrays
14
+	if (password.constructor == String) password = UTF8.stringToBytes(password);
15
+	if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
16
+	/* else, assume byte arrays already */
17
+
18
+	// Defaults
19
+	var hasher = options && options.hasher || C.SHA1,
20
+	    iterations = options && options.iterations || 1;
21
+
22
+	// Pseudo-random function
23
+	function PRF(password, salt) {
24
+		return C.HMAC(hasher, salt, password, { asBytes: true });
25
+	}
26
+
27
+	// Generate key
28
+	var derivedKeyBytes = [],
29
+	    blockindex = 1;
30
+	while (derivedKeyBytes.length < keylen) {
31
+		var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
32
+		for (var u = block, i = 1; i < iterations; i++) {
33
+			u = PRF(password, u);
34
+			for (var j = 0; j < block.length; j++) block[j] ^= u[j];
35
+		}
36
+		derivedKeyBytes = derivedKeyBytes.concat(block);
37
+		blockindex++;
38
+	}
39
+
40
+	// Truncate excess bytes
41
+	derivedKeyBytes.length = keylen;
42
+
43
+	return options && options.asBytes ? derivedKeyBytes :
44
+	       options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
45
+	       util.bytesToHex(derivedKeyBytes);
46
+
47
+};
48
+
49
+})();

+ 88 - 0
utils/lib/PBKDF2Async.js

@@ -0,0 +1,88 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8,
9
+    Binary = charenc.Binary;
10
+
11
+if (!C.nextTick) {
12
+    // node.js has setTime out but prefer process.nextTick
13
+    if (typeof process != 'undefined' && typeof process.nextTick !== 'undefined') {
14
+        C.nextTick = process.nextTick;
15
+    } else if (typeof setTimeout !== 'undefined') {
16
+        C.nextTick = function (callback) {
17
+            setTimeout(callback, 0);
18
+        };
19
+    }
20
+}
21
+
22
+C.PBKDF2Async = function (password, salt, keylen, callback, options) {
23
+
24
+    // Convert to byte arrays
25
+    if (password.constructor == String) password = UTF8.stringToBytes(password);
26
+    if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
27
+    /* else, assume byte arrays already */
28
+
29
+    // Defaults
30
+    var hasher = options && options.hasher || C.SHA1,
31
+        iterations = options && options.iterations || 1;
32
+
33
+    // Progress callback option
34
+    var progressChangeHandler = options && options.onProgressChange;
35
+    var totalIterations = Math.ceil(keylen / hasher._digestsize) * iterations;
36
+    function fireProgressChange(currentIteration) {
37
+        if (progressChangeHandler) {
38
+            var iterationsSoFar = derivedKeyBytes.length / hasher._digestsize * iterations + currentIteration;
39
+            setTimeout(function () {
40
+                progressChangeHandler(Math.round(iterationsSoFar / totalIterations * 100));
41
+            }, 0);
42
+        }
43
+    }
44
+
45
+    // Pseudo-random function
46
+    function PRF(password, salt) {
47
+        return C.HMAC(hasher, salt, password, { asBytes: true });
48
+    }
49
+
50
+    var nextTick = C.nextTick;
51
+
52
+    // Generate key
53
+    var derivedKeyBytes = [],
54
+        blockindex = 1;
55
+
56
+    var outer, inner;
57
+    nextTick(outer = function () {
58
+        if (derivedKeyBytes.length < keylen) {
59
+            var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
60
+            fireProgressChange(1);
61
+
62
+            var u = block, i = 1;
63
+            nextTick(inner = function () {
64
+                if (i < iterations) {
65
+                    u = PRF(password, u);
66
+                    for (var j = 0; j < block.length; j++) block[j] ^= u[j];
67
+                    i++;
68
+                    fireProgressChange(i);
69
+
70
+                    nextTick(inner);
71
+                } else {
72
+                    derivedKeyBytes = derivedKeyBytes.concat(block);
73
+                    blockindex++;
74
+                    nextTick(outer);
75
+                }
76
+            });
77
+        } else {
78
+            // Truncate excess bytes
79
+            derivedKeyBytes.length = keylen;
80
+            callback(
81
+                    options && options.asBytes ? derivedKeyBytes :
82
+                    options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
83
+                    util.bytesToHex(derivedKeyBytes));
84
+        }
85
+    });
86
+};
87
+
88
+})();

+ 221 - 0
utils/lib/Rabbit.js

@@ -0,0 +1,221 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8,
9
+    Binary = charenc.Binary;
10
+
11
+// Inner state
12
+var x = [],
13
+    c = [],
14
+    b;
15
+
16
+var Rabbit = C.Rabbit = {
17
+
18
+	/**
19
+	 * Public API
20
+	 */
21
+
22
+	encrypt: function (message, password) {
23
+
24
+		var
25
+
26
+		    // Convert to bytes
27
+		    m = UTF8.stringToBytes(message),
28
+
29
+		    // Generate random IV
30
+		    iv = util.randomBytes(8),
31
+
32
+		    // Generate key
33
+		    k = password.constructor == String ?
34
+		        // Derive key from passphrase
35
+		        C.PBKDF2(password, iv, 32, { asBytes: true }) :
36
+		        // else, assume byte array representing cryptographic key
37
+		        password;
38
+
39
+		// Encrypt
40
+		Rabbit._rabbit(m, k, util.bytesToWords(iv));
41
+
42
+		// Return ciphertext
43
+		return util.bytesToBase64(iv.concat(m));
44
+
45
+	},
46
+
47
+	decrypt: function (ciphertext, password) {
48
+
49
+		var
50
+
51
+		    // Convert to bytes
52
+		    c = util.base64ToBytes(ciphertext),
53
+
54
+		    // Separate IV and message
55
+		    iv = c.splice(0, 8),
56
+
57
+		    // Generate key
58
+		    k = password.constructor == String ?
59
+		        // Derive key from passphrase
60
+		        C.PBKDF2(password, iv, 32, { asBytes: true }) :
61
+		        // else, assume byte array representing cryptographic key
62
+		        password;
63
+
64
+		// Decrypt
65
+		Rabbit._rabbit(c, k, util.bytesToWords(iv));
66
+
67
+		// Return plaintext
68
+		return UTF8.bytesToString(c);
69
+
70
+	},
71
+
72
+
73
+	/**
74
+	 * Internal methods
75
+	 */
76
+
77
+	// Encryption/decryption scheme
78
+	_rabbit: function (m, k, iv) {
79
+
80
+		Rabbit._keysetup(k);
81
+		if (iv) Rabbit._ivsetup(iv);
82
+
83
+		for (var s = [], i = 0; i < m.length; i++) {
84
+
85
+			if (i % 16 == 0) {
86
+
87
+				// Iterate the system
88
+				Rabbit._nextstate();
89
+
90
+				// Generate 16 bytes of pseudo-random data
91
+				s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16);
92
+				s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16);
93
+				s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16);
94
+				s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16);
95
+
96
+				// Swap endian
97
+				for (var j = 0; j < 4; j++) {
98
+					s[j] = ((s[j] <<  8) | (s[j] >>> 24)) & 0x00FF00FF |
99
+					       ((s[j] << 24) | (s[j] >>>  8)) & 0xFF00FF00;
100
+				}
101
+
102
+				// Convert words to bytes
103
+				for (var b = 120; b >= 0; b -= 8)
104
+					s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF;
105
+
106
+			}
107
+
108
+			m[i] ^= s[i % 16];
109
+
110
+		}
111
+
112
+	},
113
+
114
+	// Key setup scheme
115
+	_keysetup: function (k) {
116
+
117
+		// Generate initial state values
118
+		x[0] = k[0];
119
+		x[2] = k[1];
120
+		x[4] = k[2];
121
+		x[6] = k[3];
122
+		x[1] = (k[3] << 16) | (k[2] >>> 16);
123
+		x[3] = (k[0] << 16) | (k[3] >>> 16);
124
+		x[5] = (k[1] << 16) | (k[0] >>> 16);
125
+		x[7] = (k[2] << 16) | (k[1] >>> 16);
126
+
127
+		// Generate initial counter values
128
+		c[0] = util.rotl(k[2], 16);
129
+		c[2] = util.rotl(k[3], 16);
130
+		c[4] = util.rotl(k[0], 16);
131
+		c[6] = util.rotl(k[1], 16);
132
+		c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF);
133
+		c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF);
134
+		c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF);
135
+		c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF);
136
+
137
+		// Clear carry bit
138
+		b = 0;
139
+
140
+		// Iterate the system four times
141
+		for (var i = 0; i < 4; i++) Rabbit._nextstate();
142
+
143
+		// Modify the counters
144
+		for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7];
145
+
146
+	},
147
+
148
+	// IV setup scheme
149
+	_ivsetup: function (iv) {
150
+
151
+		// Generate four subvectors
152
+		var i0 = util.endian(iv[0]),
153
+		    i2 = util.endian(iv[1]),
154
+		    i1 = (i0 >>> 16) | (i2 & 0xFFFF0000),
155
+		    i3 = (i2 <<  16) | (i0 & 0x0000FFFF);
156
+
157
+		// Modify counter values
158
+		c[0] ^= i0;
159
+		c[1] ^= i1;
160
+		c[2] ^= i2;
161
+		c[3] ^= i3;
162
+		c[4] ^= i0;
163
+		c[5] ^= i1;
164
+		c[6] ^= i2;
165
+		c[7] ^= i3;
166
+
167
+		// Iterate the system four times
168
+		for (var i = 0; i < 4; i++) Rabbit._nextstate();
169
+
170
+	},
171
+
172
+	// Next-state function
173
+	_nextstate: function () {
174
+
175
+		// Save old counter values
176
+		for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i];
177
+
178
+		// Calculate new counter values
179
+		c[0] = (c[0] + 0x4D34D34D + b) >>> 0;
180
+		c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0;
181
+		c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0;
182
+		c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0;
183
+		c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0;
184
+		c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0;
185
+		c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0;
186
+		c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0;
187
+		b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0;
188
+
189
+		// Calculate the g-values
190
+		for (var g = [], i = 0; i < 8; i++) {
191
+
192
+			var gx = (x[i] + c[i]) >>> 0;
193
+
194
+			// Construct high and low argument for squaring
195
+			var ga = gx & 0xFFFF,
196
+			    gb = gx >>> 16;
197
+
198
+			// Calculate high and low result of squaring
199
+			var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb,
200
+			    gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0;
201
+
202
+			// High XOR low
203
+			g[i] = gh ^ gl;
204
+
205
+		}
206
+
207
+		// Calculate new state values
208
+		x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16));
209
+		x[1] = g[1] + ((g[0] <<  8) | (g[0] >>> 24)) + g[7];
210
+		x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16));
211
+		x[3] = g[3] + ((g[2] <<  8) | (g[2] >>> 24)) + g[1];
212
+		x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16));
213
+		x[5] = g[5] + ((g[4] <<  8) | (g[4] >>> 24)) + g[3];
214
+		x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16));
215
+		x[7] = g[7] + ((g[6] <<  8) | (g[6] >>> 24)) + g[5];
216
+
217
+	}
218
+
219
+};
220
+
221
+})();

+ 86 - 0
utils/lib/SHA1.js

@@ -0,0 +1,86 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8,
9
+    Binary = charenc.Binary;
10
+
11
+// Public API
12
+var SHA1 = C.SHA1 = function (message, options) {
13
+	var digestbytes = util.wordsToBytes(SHA1._sha1(message));
14
+	return options && options.asBytes ? digestbytes :
15
+	       options && options.asString ? Binary.bytesToString(digestbytes) :
16
+	       util.bytesToHex(digestbytes);
17
+};
18
+
19
+// The core
20
+SHA1._sha1 = function (message) {
21
+
22
+	// Convert to byte array
23
+	if (message.constructor == String) message = UTF8.stringToBytes(message);
24
+	/* else, assume byte array already */
25
+
26
+	var m  = util.bytesToWords(message),
27
+	    l  = message.length * 8,
28
+	    w  =  [],
29
+	    H0 =  1732584193,
30
+	    H1 = -271733879,
31
+	    H2 = -1732584194,
32
+	    H3 =  271733878,
33
+	    H4 = -1009589776;
34
+
35
+	// Padding
36
+	m[l >> 5] |= 0x80 << (24 - l % 32);
37
+	m[((l + 64 >>> 9) << 4) + 15] = l;
38
+
39
+	for (var i = 0; i < m.length; i += 16) {
40
+
41
+		var a = H0,
42
+		    b = H1,
43
+		    c = H2,
44
+		    d = H3,
45
+		    e = H4;
46
+
47
+		for (var j = 0; j < 80; j++) {
48
+
49
+			if (j < 16) w[j] = m[i + j];
50
+			else {
51
+				var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];
52
+				w[j] = (n << 1) | (n >>> 31);
53
+			}
54
+
55
+			var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
56
+			         j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
57
+			         j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
58
+			         j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
59
+			                  (H1 ^ H2 ^ H3) - 899497514);
60
+
61
+			H4 =  H3;
62
+			H3 =  H2;
63
+			H2 = (H1 << 30) | (H1 >>> 2);
64
+			H1 =  H0;
65
+			H0 =  t;
66
+
67
+		}
68
+
69
+		H0 += a;
70
+		H1 += b;
71
+		H2 += c;
72
+		H3 += d;
73
+		H4 += e;
74
+
75
+	}
76
+
77
+	return [H0, H1, H2, H3, H4];
78
+
79
+};
80
+
81
+// Package private blocksize
82
+SHA1._blocksize = 16;
83
+
84
+SHA1._digestsize = 20;
85
+
86
+})();

+ 130 - 0
utils/lib/SHA256.js

@@ -0,0 +1,130 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8,
9
+    Binary = charenc.Binary;
10
+
11
+// Constants
12
+var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
13
+          0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
14
+          0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
15
+          0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
16
+          0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
17
+          0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
18
+          0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
19
+          0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
20
+          0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
21
+          0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
22
+          0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
23
+          0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
24
+          0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
25
+          0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
26
+          0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
27
+          0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ];
28
+
29
+// Public API
30
+var SHA256 = C.SHA256 = function (message, options) {
31
+	var digestbytes = util.wordsToBytes(SHA256._sha256(message));
32
+	return options && options.asBytes ? digestbytes :
33
+	       options && options.asString ? Binary.bytesToString(digestbytes) :
34
+	       util.bytesToHex(digestbytes);
35
+};
36
+
37
+// The core
38
+SHA256._sha256 = function (message) {
39
+
40
+	// Convert to byte array
41
+	if (message.constructor == String) message = UTF8.stringToBytes(message);
42
+	/* else, assume byte array already */
43
+
44
+	var m = util.bytesToWords(message),
45
+	    l = message.length * 8,
46
+	    H = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
47
+	          0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ],
48
+	    w = [],
49
+	    a, b, c, d, e, f, g, h, i, j,
50
+	    t1, t2;
51
+
52
+	// Padding
53
+	m[l >> 5] |= 0x80 << (24 - l % 32);
54
+	m[((l + 64 >> 9) << 4) + 15] = l;
55
+
56
+	for (var i = 0; i < m.length; i += 16) {
57
+
58
+		a = H[0];
59
+		b = H[1];
60
+		c = H[2];
61
+		d = H[3];
62
+		e = H[4];
63
+		f = H[5];
64
+		g = H[6];
65
+		h = H[7];
66
+
67
+		for (var j = 0; j < 64; j++) {
68
+
69
+			if (j < 16) w[j] = m[j + i];
70
+			else {
71
+
72
+				var gamma0x = w[j - 15],
73
+				    gamma1x = w[j - 2],
74
+				    gamma0  = ((gamma0x << 25) | (gamma0x >>>  7)) ^
75
+				              ((gamma0x << 14) | (gamma0x >>> 18)) ^
76
+				               (gamma0x >>> 3),
77
+				    gamma1  = ((gamma1x <<  15) | (gamma1x >>> 17)) ^
78
+				              ((gamma1x <<  13) | (gamma1x >>> 19)) ^
79
+				               (gamma1x >>> 10);
80
+
81
+				w[j] = gamma0 + (w[j - 7] >>> 0) +
82
+				       gamma1 + (w[j - 16] >>> 0);
83
+
84
+			}
85
+
86
+			var ch  = e & f ^ ~e & g,
87
+			    maj = a & b ^ a & c ^ b & c,
88
+			    sigma0 = ((a << 30) | (a >>>  2)) ^
89
+			             ((a << 19) | (a >>> 13)) ^
90
+			             ((a << 10) | (a >>> 22)),
91
+			    sigma1 = ((e << 26) | (e >>>  6)) ^
92
+			             ((e << 21) | (e >>> 11)) ^
93
+			             ((e <<  7) | (e >>> 25));
94
+
95
+
96
+			t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0);
97
+			t2 = sigma0 + maj;
98
+
99
+			h = g;
100
+			g = f;
101
+			f = e;
102
+			e = (d + t1) >>> 0;
103
+			d = c;
104
+			c = b;
105
+			b = a;
106
+			a = (t1 + t2) >>> 0;
107
+
108
+		}
109
+
110
+		H[0] += a;
111
+		H[1] += b;
112
+		H[2] += c;
113
+		H[3] += d;
114
+		H[4] += e;
115
+		H[5] += f;
116
+		H[6] += g;
117
+		H[7] += h;
118
+
119
+	}
120
+
121
+	return H;
122
+
123
+};
124
+
125
+// Package private blocksize
126
+SHA256._blocksize = 16;
127
+
128
+SHA256._digestsize = 32;
129
+
130
+})();

+ 311 - 0
utils/main.js

@@ -0,0 +1,311 @@
1
+import common from '../utils/util';
2
+var app = getApp();
3
+
4
+function getData(url, callback) {
5
+  //console.log("加密前的结果为===", url);
6
+  var url = common.Encrypt(url);
7
+  //console.log("加密后的结果为===",url);
8
+  wx.request({
9
+    url: app.globalData.serverUrl + url,
10
+    success: function (res) {
11
+      if (res.statusCode)
12
+        common.checkError(res.statusCode);
13
+      var data = res.data.result;
14
+      callback(data);
15
+    },
16
+    fail: function () {
17
+      wx.redirectTo({
18
+        url: './error',
19
+      });
20
+    },
21
+  });
22
+}
23
+
24
+function postData(url, postData, callback) {
25
+  var url = common.Encrypt(url);
26
+  //console.log("加密后的结果为===",url);
27
+  wx.request({
28
+    url: app.globalData.serverUrl + url,
29
+    method: "POST",
30
+    data: postData,
31
+    success: function (res) {
32
+      if (res.statusCode)
33
+        common.checkError(res.statusCode);
34
+      var data = res.data.result;
35
+      callback(data);
36
+    },
37
+    fail: function () {
38
+      wx.showToast({
39
+        title: '服务器忙,请稍候再试!',
40
+        duration: 3000
41
+      });
42
+      wx.redirectTo({
43
+        url: './error',
44
+      });
45
+    },
46
+  });
47
+}
48
+
49
+function getLocalHost(callback) {
50
+  if (!app.globalData.IsProduction) {
51
+    var url = common.Encrypt("Ping");
52
+    wx.request({
53
+      url: app.globalData.serverUrlLocalhost + url,
54
+      success: function (res) {
55
+        app.globalData.serverUrl = app.globalData.serverUrlLocalhost;
56
+        callback();
57
+      },
58
+      fail: function () {
59
+        app.globalData.serverUrl = app.globalData.serverUrlServer;
60
+        callback();
61
+      },
62
+    });
63
+  }
64
+  else {
65
+    app.globalData.serverUrl = app.globalData.serverUrlServer;
66
+    callback();
67
+  }
68
+}
69
+
70
+function shareGroup(shareTickets, isShared) {
71
+  // 转发成功
72
+  console.log("shareTickets:" + shareTickets);
73
+  if (shareTickets && shareTickets.length > 0) {
74
+    var that = this;
75
+    for (var i = 0; i < shareTickets.length; i++) {
76
+      wx.getShareInfo({
77
+        shareTicket: shareTickets[i],
78
+        success: function (groupInfo) {
79
+          wx.login({
80
+            success: function (res0) {
81
+              console.log("groupInfo:" + groupInfo);
82
+              that.postData('AddSpatialIntelligenceGroup', {
83
+                Code: res0.code,
84
+                UserID: app.globalData.userInfo.UserID,
85
+                GroupInfo: groupInfo,
86
+                IsShared: isShared,
87
+              }, function (data) {
88
+
89
+              });
90
+            }
91
+          });
92
+        },
93
+        fail: function (err) {
94
+          console.log(err);
95
+        },
96
+      });
97
+    }
98
+  }
99
+}
100
+
101
+
102
+function payMoney(payType, money, callback) {
103
+  console.log(money);
104
+  //登录认证
105
+  wx.login({
106
+    success: function (res) {
107
+      if (res.code) {
108
+        console.log('获取用户登录态成功!' + res.code);
109
+        //预支付
110
+        getData('PayLogin?code=' + res.code + '&payType=' + payType + '&money=' + money, function (data) {
111
+          if (data && data.timeStamp) {
112
+            //微信支付
113
+            wx.requestPayment({
114
+              'timeStamp': data.timeStamp.toString(),
115
+              'nonceStr': data.nonceStr,
116
+              'package': data.package,
117
+              'signType': 'MD5',
118
+              'paySign': data.paySign,
119
+              'success': function (res3) {
120
+                console.log("success:" + res3);
121
+                callback();
122
+              },
123
+              'fail': function (err) {
124
+                if (err && err.errMsg && err.errMsg.indexOf("fail cancel")) {
125
+
126
+                }
127
+                else {
128
+                  wx.showToast({
129
+                    title: '服务器忙,请稍候再试!',
130
+                    duration: 3000
131
+                  });
132
+                  wx.redirectTo({
133
+                    url: './error',
134
+                  });
135
+                }
136
+              }
137
+            });
138
+          }
139
+        });
140
+
141
+      } else {
142
+        console.log('获取用户登录态失败!' + res.errMsg);
143
+      }
144
+    }
145
+  });
146
+}
147
+function downloadImage(scoreID) {
148
+  wx.showLoading({
149
+    title: '下载中_然后长按保存',
150
+  });
151
+
152
+  var that = this;
153
+  getData('MakeSchulteShare?ScoreID=' + scoreID, function (data) {
154
+
155
+    setTimeout(function () {
156
+      wx.downloadFile({
157
+        url: "https://schulte-1253256735.file.myqcloud.com/share" + scoreID + ".jpg",
158
+        success: function (res) {
159
+          wx.hideLoading();
160
+          wx.previewImage({
161
+            current: res.tempFilePath, // 当前显示图片的http链接
162
+            urls: [res.tempFilePath] // 需要预览的图片http链接列表
163
+          })
164
+        },
165
+        fail: function () {
166
+          wx.hideLoading();
167
+          getData('MakeSchulteShare?ScoreID=' + scoreID, function (data) { });
168
+          wx.showToast({
169
+            title: '请稍候再试!',
170
+            duration: 2000
171
+          });
172
+        }
173
+      });
174
+    }, 2000);
175
+
176
+  });
177
+}
178
+
179
+function getTimeFormat(duration) {
180
+  //console.log("duration:" + duration);
181
+  var arr = ['', '', '']
182
+  if (duration.indexOf("'") > 0)
183
+    arr[0] = duration.substring(0, duration.indexOf("'"));
184
+  if (duration.indexOf(".") > 0) {
185
+    arr[1] = duration.substring(duration.indexOf("'") + 1, duration.indexOf(".") + 1);
186
+    arr[2] = duration.substring(duration.indexOf(".") + 1, duration.indexOf('"'));
187
+  }
188
+  else {
189
+    arr[1] = duration.substring(duration.indexOf("'") + 1, duration.indexOf('"'));
190
+  }
191
+  return arr;
192
+}
193
+
194
+function getWindowHeight() {
195
+
196
+  var height = app.globalData.systemInfo.windowHeight;
197
+  //console.log("app.globalData.systemInfo.windowHeight:" + app.globalData.systemInfo.windowHeight * 2);
198
+  if (app.globalData.systemInfo.model) {
199
+    if (height == 504 && (
200
+      app.globalData.systemInfo.model.indexOf("iPhone 6<") >= 0
201
+      || app.globalData.systemInfo.model.indexOf("iPhone 7<") >= 0
202
+      || app.globalData.systemInfo.model.indexOf("iPhone 6s<") >= 0
203
+      || app.globalData.systemInfo.model.indexOf("iPhone 5") >= 0
204
+      || app.globalData.systemInfo.model.indexOf("iPhone SE") >= 0
205
+    )) {
206
+      height = 596;
207
+    }
208
+  }
209
+
210
+  height = height * 2;
211
+  if (app.globalData.systemInfo.system && app.globalData.systemInfo.system.indexOf("Android") >= 0) {
212
+    height = height + 168;
213
+  }
214
+  else {
215
+    height = height + 50;
216
+  }
217
+  //console.log("height:" + height);
218
+
219
+  return height;
220
+}
221
+
222
+//获取存储数据,若不存在,则获得缺省值。
223
+function getStorageValue(obj, name, defaultStatus, callback) {
224
+  wx.getStorage({
225
+    key: name,
226
+    success: function (res) {
227
+      obj.data[name] = res.data;
228
+      obj.setData(obj.data);
229
+      callback();
230
+    },
231
+    fail: function (res) {
232
+      obj.data[name] = defaultStatus;
233
+      obj.setData(obj.data);
234
+      callback();
235
+    },
236
+  });
237
+}
238
+
239
+function getDifficulty(num) {
240
+  switch (Number(num)) {
241
+    case 3:
242
+    case 4:
243
+    case 5:
244
+      return "EASY";
245
+    case 6:
246
+    case 7:
247
+      return "HARD";
248
+    case 8:
249
+    case 9:
250
+      return "SUPER";
251
+  }
252
+}
253
+
254
+
255
+function getProgramList() {
256
+  return [
257
+    {
258
+      id: 89,
259
+      appId: 'wx46a7b4c420e6d38f',
260
+      path: 'pages/index/start?SourceID=' + app.globalData.ProgramID,
261
+    },
262
+    {
263
+      id: 98,
264
+      appId: 'wx331e8dd070f01d0e',
265
+      path: 'pages/index/index?SourceID=' + app.globalData.ProgramID,
266
+    },
267
+    {
268
+      id: 99,
269
+      appId: 'wxb54a6d5aff836ee3',
270
+      path: 'pages/index/index?SourceID=' + app.globalData.ProgramID,
271
+    },
272
+    {
273
+      id: 106,
274
+      appId: 'wx313a8f2c0741efe1',
275
+      path: 'pages/index/index?SourceID=' + app.globalData.ProgramID,
276
+    },
277
+    {
278
+      id: 90,
279
+      appId: 'wxa5e33c61fe37dd01',
280
+      path: 'pages/index/index?SourceID=' + app.globalData.ProgramID,
281
+    },
282
+  ];
283
+}
284
+
285
+
286
+function gotoFeedback() {
287
+  wx.navigateToMiniProgram({
288
+    appId: "wx80059777521b897c",
289
+    path: "pages/index/feedback",
290
+    extraData: {
291
+    },
292
+    success(res) {
293
+      // 打开成功
294
+    }
295
+  });
296
+}
297
+
298
+module.exports = {
299
+  getData: getData,
300
+  postData: postData,
301
+  shareGroup: shareGroup,
302
+  payMoney: payMoney,
303
+  downloadImage: downloadImage,
304
+  getLocalHost: getLocalHost,
305
+  getTimeFormat: getTimeFormat,
306
+  getWindowHeight: getWindowHeight,
307
+  getStorageValue: getStorageValue,
308
+  getDifficulty: getDifficulty,
309
+  getProgramList: getProgramList,
310
+  gotoFeedback: gotoFeedback,
311
+}

+ 298 - 11
utils/util.js

@@ -1,19 +1,306 @@
1
-const formatTime = date => {
2
-  const year = date.getFullYear()
3
-  const month = date.getMonth() + 1
4
-  const day = date.getDate()
5
-  const hour = date.getHours()
6
-  const minute = date.getMinutes()
7
-  const second = date.getSeconds()
1
+var Crypto = require('cryptojs.js').Crypto;
2
+var app = getApp();
8 3
 
9
-  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
4
+function formatTime(date) {
5
+  var year = date.getFullYear()
6
+  var month = date.getMonth() + 1
7
+  var day = date.getDate()
8
+
9
+  var hour = date.getHours()
10
+  var minute = date.getMinutes()
11
+  var second = date.getSeconds()
12
+
13
+
14
+  return [year, month, day].map(formatNumber).join('.') + ' ' + [hour, minute, second].map(formatNumber).join(':')
10 15
 }
11 16
 
12
-const formatNumber = n => {
17
+function formatNumber(n) {
13 18
   n = n.toString()
14 19
   return n[1] ? n : '0' + n
15 20
 }
16 21
 
17
-module.exports = {
18
-  formatTime: formatTime
22
+//给字符串左侧补零
23
+function addZero(str, length) {
24
+  while (str.length < length) {
25
+    str = "0" + str;
26
+  }
27
+  return str;
28
+}
29
+
30
+function getMinuteSecond(second, chs) {
31
+  if (!second)
32
+    second = 0;
33
+  var secondUnit = "\"";
34
+  var minuteUnit = "'";
35
+  var hourUnit = ":";
36
+  if (chs) {
37
+    secondUnit = "秒";
38
+    minuteUnit = "分";
39
+    hourUnit = "时";
40
+    //second = Math.round(second);
41
+  }
42
+  if (second < 60)
43
+    return second + secondUnit;
44
+  else {
45
+    var minute = Math.floor(second / 60);
46
+    second = Math.round((second - minute * 60) * 1000) / 1000;
47
+
48
+    if (minute >= 60) {
49
+      var hour = Math.floor(minute / 60);
50
+      minute = minute - hour * 60;
51
+
52
+      if (minute == 0 && second == 0)
53
+        return hour + hourUnit;
54
+      else if (second == 0)
55
+        return hour + hourUnit + minute + minuteUnit;
56
+      else
57
+        return hour + hourUnit + minute + minuteUnit + second + secondUnit;
58
+    }
59
+    else {
60
+      if (second == 0)
61
+        return minute + minuteUnit;
62
+      else
63
+        return minute + minuteUnit + second + secondUnit;
64
+    }
65
+  }
66
+}
67
+
68
+function Random(start, end) {
69
+  var result = parseInt(Math.random() * (end - start + 1) + start);
70
+  return result;
71
+}
72
+//打乱数组
73
+function RandomArray(arr) {
74
+  var arrResult = [];
75
+  var maxCount = 0;
76
+  do {
77
+    var rnd = Random(0, arr.length - 1);
78
+    if (arr[rnd]) {
79
+      arrResult.push(arr[rnd]);
80
+      arr[rnd] = null;
81
+    }
82
+    maxCount++;
83
+  }
84
+  while (arrResult.length < arr.length && maxCount < 1000);
85
+  return arrResult;
86
+}
87
+
88
+function Unique(arr) {
89
+  var res = [];
90
+  var json = {};
91
+  for (var i = 0; i < arr.length; i++) {
92
+    if (!json[arr[i]]) {
93
+      res.push(arr[i]);
94
+      json[arr[i]] = 1;
95
+    }
96
+  }
97
+  return res;
98
+}
99
+
100
+function getEnumerationName(id, list) {
101
+  for (var i = 0; i < list.length; i++) {
102
+    if (id == list[i].EnumID) {
103
+      return list[i].Name;
104
+    }
105
+  }
106
+  return "";
107
+}
108
+
109
+function getEnumerationNameByDescription(description, list) {
110
+  for (var i = 0; i < list.length; i++) {
111
+    if (description == list[i].Description) {
112
+      return list[i].Name;
113
+    }
114
+  }
115
+  return "";
116
+}
117
+
118
+function getStringMaxLength(str, len) {
119
+  if (str.length > len)
120
+    return str.substr(0, len) + "...";
121
+  else
122
+    return str;
19 123
 }
124
+
125
+function sort(array, sort_order, obj, objType, obj2, objType2) {
126
+  for (var i = 0; i < array.length - 1; i++) {
127
+    for (var j = i + 1; j < array.length; j++) {
128
+      var check;
129
+      if (objType == "Number") {
130
+        if (sort_order == "ASC")
131
+          check = array[i][obj] > array[j][obj];
132
+        else
133
+          check = array[i][obj] < array[j][obj];
134
+      }
135
+      else {
136
+        //console.log("array["+i+"]:"+array[i][obj]);
137
+        //console.log("array["+j+"]:"+array[j][obj]);
138
+        if (array[i][obj] && array[j][obj]) {
139
+          try {
140
+            if (sort_order == "ASC")
141
+              check = array[i][obj].toString().localeCompare(array[j][obj].toString()) >= 0;
142
+            else if (sort_order == "DESC")
143
+              check = array[i][obj].toString().localeCompare(array[j][obj].toString()) < 0;
144
+          }
145
+          catch (ex) {
146
+            console.log("ex:" + ex);
147
+            if (sort_order == "ASC")
148
+              check = array[i][obj].toString() >= array[j][obj].toString();
149
+            else if (sort_order == "DESC")
150
+              check = array[i][obj].toString() < array[j][obj].toString();
151
+
152
+          }
153
+        }
154
+        else {
155
+          check = false;
156
+        }
157
+      }
158
+      if (check) {
159
+        var temp = swap(array[i], array[j]);
160
+        array[i] = temp.a;
161
+        array[j] = temp.b;
162
+      }
163
+    }
164
+  }
165
+  return array;
166
+
167
+  function swap(a, b) {
168
+    var tempA = JSON.stringify(a);
169
+    var tempB = JSON.stringify(b);
170
+    return {
171
+      a: JSON.parse(tempB),
172
+      b: JSON.parse(tempA),
173
+    }
174
+  }
175
+}
176
+////测试sort
177
+// var a = [
178
+//   {
179
+//     time: "2017-2-1",
180
+//     a: 3,
181
+//   }, {
182
+//     time: "2017-4-1",
183
+//     a: 5,
184
+//   }, {
185
+//     time: "2017-1-1",
186
+//     a: 6
187
+//   },{
188
+//     time: "2017-2-1",
189
+//     a: 3
190
+//   },
191
+// ];
192
+// console.log(a);
193
+// // var a = common.sort(a,"ASC", "time","String");
194
+// // console.log(a);
195
+// var a = common.sort(a,"DESC", "time","String");
196
+// console.log(a);
197
+// //var a = common.sort(a,"DESC", "a","Number");
198
+// // console.log(a);
199
+
200
+function checkError(err) {
201
+  switch (err) {
202
+    case 404:
203
+    case 500:
204
+    case 501:
205
+    case 502:
206
+    case 503:
207
+    case 504:
208
+    case 505:
209
+      wx.redirectTo({
210
+        url: './error',
211
+      });
212
+      break;
213
+  }
214
+  return null;
215
+}
216
+
217
+function Encrypt(word) {
218
+  var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
219
+  var eb = Crypto.charenc.UTF8.stringToBytes(word);
220
+  var kb = Crypto.charenc.UTF8.stringToBytes(app.globalData.Key);//KEY
221
+  var vb = Crypto.charenc.UTF8.stringToBytes(app.globalData.IV);//IV
222
+  var ub = Crypto.AES.encrypt(eb, kb, { iv: vb, mode: mode, asBpytes: true });
223
+  return ub;
224
+}
225
+
226
+function Decrypt(word) {
227
+  var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
228
+  var eb = Crypto.util.base64ToBytes(word);
229
+  var kb = Crypto.charenc.UTF8.stringToBytes(app.globalData.Key);//KEY
230
+  var vb = Crypto.charenc.UTF8.stringToBytes(app.globalData.IV);//IV
231
+  var ub = Crypto.AES.decrypt(eb, kb, { asBpytes: true, mode: mode, iv: vb });
232
+  return ub;
233
+}
234
+
235
+function isExistStr(str1, str2) {
236
+  var result = false;
237
+  if (str1) {
238
+    if (str1.toString().indexOf(str2) >= 0) {
239
+      result = true;
240
+    }
241
+  }
242
+  return result;
243
+}
244
+
245
+function getSystemHeight() {
246
+  var systemInfo = wx.getSystemInfoSync();
247
+  var height = systemInfo.windowHeight;
248
+  if (systemInfo.model) {
249
+    if (height == 603 && systemInfo.model.indexOf("Plus") > 0) {
250
+      height = 625;
251
+    }
252
+    else if (height == 504 && (
253
+      systemInfo.model.indexOf("iPhone 6<") >= 0
254
+      || systemInfo.model.indexOf("iPhone 7<") >= 0
255
+      || systemInfo.model.indexOf("iPhone 6s<") >= 0
256
+      || systemInfo.model.indexOf("iPhone 5") >= 0
257
+      || systemInfo.model.indexOf("iPhone SE") >= 0
258
+    )) {
259
+      height = 596;
260
+    }
261
+  }
262
+
263
+  height = height * 2;
264
+  if (systemInfo.system && systemInfo.system.indexOf("Android") >= 0) {
265
+    height = height + 168;
266
+  }
267
+  return height;
268
+}
269
+
270
+//获取存储数据,若不存在,则获得缺省值。
271
+function getStorageValue(obj, name, defaultStatus, callback) {
272
+  wx.getStorage({
273
+    key: name,
274
+    success: function (res) {
275
+      obj.data[name] = res.data;
276
+      obj.setData(obj.data);
277
+      if (callback)
278
+        callback();
279
+    },
280
+    fail: function (res) {
281
+      obj.data[name] = defaultStatus;
282
+      obj.setData(obj.data);
283
+      if (callback)
284
+        callback();
285
+    },
286
+  });
287
+}
288
+
289
+module.exports = {
290
+  formatTime: formatTime,
291
+  getMinuteSecond: getMinuteSecond,
292
+  random: Random,
293
+  randomArray: RandomArray,
294
+  unique: Unique,
295
+  getEnumerationName: getEnumerationName,
296
+  getStringMaxLength: getStringMaxLength,
297
+  sort: sort,
298
+  addZero: addZero,
299
+  checkError: checkError,
300
+  Encrypt: Encrypt,
301
+  Decrypt: Decrypt,
302
+  getEnumerationNameByDescription: getEnumerationNameByDescription,
303
+  isExistStr: isExistStr,
304
+  getStorageValue: getStorageValue,
305
+  getSystemHeight: getSystemHeight,
306
+}