chengjie 7 år sedan
incheckning
014049e9c7
85 ändrade filer med 4571 tillägg och 0 borttagningar
  1. 10 0
      app.js
  2. 14 0
      app.json
  3. 26 0
      app.wxss
  4. BIN
      images/01001.png
  5. BIN
      images/01002.png
  6. BIN
      images/01003.png
  7. BIN
      images/01004.png
  8. BIN
      images/01005.png
  9. BIN
      images/02001.png
  10. BIN
      images/02002.png
  11. BIN
      images/02003.png
  12. BIN
      images/02004.gif
  13. BIN
      images/02005.png
  14. BIN
      images/02006.png
  15. BIN
      images/02007.png
  16. BIN
      images/02008.png
  17. BIN
      images/02009.png
  18. BIN
      images/02010.png
  19. BIN
      images/02011.png
  20. BIN
      images/02012.png
  21. BIN
      images/02013.png
  22. BIN
      images/02014.png
  23. BIN
      images/02015.png
  24. BIN
      images/02016.png
  25. BIN
      images/02017.png
  26. BIN
      images/02018.png
  27. BIN
      images/02019.png
  28. BIN
      images/02020.png
  29. BIN
      images/02021.png
  30. BIN
      images/03001.png
  31. BIN
      images/03002.png
  32. BIN
      images/03003.png
  33. BIN
      images/03004.png
  34. BIN
      images/04001.png
  35. BIN
      images/04002.png
  36. BIN
      images/04003.png
  37. BIN
      images/04004.png
  38. BIN
      images/04005.png
  39. BIN
      images/04006.png
  40. BIN
      images/04007.png
  41. BIN
      images/04008.png
  42. BIN
      images/04009.png
  43. BIN
      images/05001.png
  44. BIN
      images/05002.png
  45. BIN
      images/05003.png
  46. BIN
      images/05004.png
  47. BIN
      images/05005.png
  48. BIN
      images/05006.png
  49. BIN
      images/05007.png
  50. BIN
      images/05008.png
  51. BIN
      images/05009.png
  52. BIN
      images/05010.png
  53. BIN
      images/05011.png
  54. BIN
      images/05012.gif
  55. BIN
      images/06001.png
  56. BIN
      images/07001.png
  57. 43 0
      pages/index/index.js
  58. 4 0
      pages/index/index.json
  59. 10 0
      pages/index/index.wxml
  60. 41 0
      pages/index/index.wxss
  61. 95 0
      pages/main/index.js
  62. 4 0
      pages/main/index.json
  63. 152 0
      pages/main/index.wxml
  64. 393 0
      pages/main/index.wxss
  65. 36 0
      pages/main/list.js
  66. 5 0
      pages/main/list.json
  67. 101 0
      pages/main/list.wxml
  68. 166 0
      pages/main/list.wxss
  69. 50 0
      project.config.json
  70. 19 0
      utils/cryptojs.js
  71. 402 0
      utils/lib/AES.js
  72. 378 0
      utils/lib/BlockModes.js
  73. 155 0
      utils/lib/Crypto.js
  74. 37 0
      utils/lib/CryptoMath.js
  75. 1003 0
      utils/lib/DES.js
  76. 38 0
      utils/lib/HMAC.js
  77. 117 0
      utils/lib/MARC4.js
  78. 158 0
      utils/lib/MD5.js
  79. 49 0
      utils/lib/PBKDF2.js
  80. 88 0
      utils/lib/PBKDF2Async.js
  81. 221 0
      utils/lib/Rabbit.js
  82. 86 0
      utils/lib/SHA1.js
  83. 130 0
      utils/lib/SHA256.js
  84. 127 0
      utils/main.js
  85. 413 0
      utils/util.js

+ 10 - 0
app.js

@@ -0,0 +1,10 @@
1
+//app.js
2
+App({
3
+  onLaunch: function () {
4
+
5
+  },
6
+  globalData: {
7
+    Version: "0.1.0",
8
+    userInfo: null
9
+  }
10
+})

+ 14 - 0
app.json

@@ -0,0 +1,14 @@
1
+{
2
+  "pages": [
3
+    "pages/index/index",
4
+    "pages/main/list",
5
+    "pages/main/index"
6
+  ],
7
+  "window": {
8
+    "backgroundTextStyle": "light",
9
+    "navigationBarBackgroundColor": "#F5E2BE",
10
+    "navigationBarTitleText":"识字",
11
+    "navigationBarTextStyle": "black",
12
+    "backgroundColor": "#F5E2BE"   
13
+  }
14
+}

+ 26 - 0
app.wxss

@@ -0,0 +1,26 @@
1
+/**app.wxss**/
2
+.container {
3
+  width:100%;
4
+  justify-content: flex-start;
5
+} 
6
+
7
+::-webkit-scrollbar {
8
+  width: 0;
9
+  height: 0;
10
+  color: transparent;
11
+  display: none;
12
+}
13
+
14
+.FlexColumn {
15
+  display: flex;
16
+  flex-direction: column;
17
+  align-items: center;
18
+  justify-content: center;
19
+}
20
+
21
+.FlexRow {
22
+  display: flex;
23
+  flex-direction: row;
24
+  align-items: center;
25
+  justify-content: center;
26
+}

BIN
images/01001.png


BIN
images/01002.png


BIN
images/01003.png


BIN
images/01004.png


BIN
images/01005.png


BIN
images/02001.png


BIN
images/02002.png


BIN
images/02003.png


BIN
images/02004.gif


BIN
images/02005.png


BIN
images/02006.png


BIN
images/02007.png


BIN
images/02008.png


BIN
images/02009.png


BIN
images/02010.png


BIN
images/02011.png


BIN
images/02012.png


BIN
images/02013.png


BIN
images/02014.png


BIN
images/02015.png


BIN
images/02016.png


BIN
images/02017.png


BIN
images/02018.png


BIN
images/02019.png


BIN
images/02020.png


BIN
images/02021.png


BIN
images/03001.png


BIN
images/03002.png


BIN
images/03003.png


BIN
images/03004.png


BIN
images/04001.png


BIN
images/04002.png


BIN
images/04003.png


BIN
images/04004.png


BIN
images/04005.png


BIN
images/04006.png


BIN
images/04007.png


BIN
images/04008.png


BIN
images/04009.png


BIN
images/05001.png


BIN
images/05002.png


BIN
images/05003.png


BIN
images/05004.png


BIN
images/05005.png


BIN
images/05006.png


BIN
images/05007.png


BIN
images/05008.png


BIN
images/05009.png


BIN
images/05010.png


BIN
images/05011.png


BIN
images/05012.gif


BIN
images/06001.png


BIN
images/07001.png


+ 43 - 0
pages/index/index.js

@@ -0,0 +1,43 @@
1
+import common from '../../utils/util';
2
+import server from '../../utils/main';
3
+
4
+const app = getApp()
5
+
6
+Page({
7
+  data: {
8
+    FileUrl: "../../",
9
+    ImageAll: ["../../images/01003.png", "../../images/01004.png", "../../images/01005.png"],
10
+    indexImage:0,
11
+  },
12
+  onReady: function (e) {
13
+  },
14
+  onLoad: function () {
15
+    this.setData({
16
+      Height: common.getSystemHeight(),
17
+      indexImage:common.random(0,2),
18
+    });
19
+
20
+    setTimeout(function(){
21
+      wx.redirectTo({
22
+        url: '../main/index'
23
+      })
24
+    },2000);
25
+  },
26
+  
27
+  onShareAppMessage: function () {
28
+    return {
29
+      title: '',
30
+      path: 'pages/index/index',
31
+      imageUrl: '../../images/07001.png',
32
+      success: function (res) {
33
+        
34
+      },
35
+      fail: function (err) {
36
+        console.log(err);
37
+      },
38
+      complete: function (res) {
39
+        console.log(res);
40
+      },
41
+    }
42
+  },
43
+})

+ 4 - 0
pages/index/index.json

@@ -0,0 +1,4 @@
1
+{
2
+  "navigationBarTitleText": "语文识字认字",
3
+  "enablePullDownRefresh": false
4
+}

+ 10 - 0
pages/index/index.wxml

@@ -0,0 +1,10 @@
1
+<view class="container FlexColumn" style='min-height:{{Height}}rpx;'>
2
+  <view class="index1 FlexRow">
3
+    <image src='../../images/01001.png' class="image01001" />
4
+  </view>
5
+  <view class="index2 FlexRow">
6
+    <image src='../../images/01002.png' class="image01002" />
7
+  </view>
8
+  <image src='{{ImageAll[indexImage]}}' class="image01003" />
9
+  
10
+</view>

+ 41 - 0
pages/index/index.wxss

@@ -0,0 +1,41 @@
1
+.container {
2
+  background-color: #F5E2BE;
3
+  justify-content: flex-start;
4
+  color: #1e1e1e;
5
+  font-weight: 500;
6
+}
7
+
8
+.index1 {
9
+  position: fixed;
10
+  top: 178rpx;
11
+  left: 0;
12
+  width:100%;
13
+}
14
+
15
+.image01001 {
16
+  width: 513rpx;
17
+  height: 516rpx;
18
+}
19
+
20
+
21
+.index2 {
22
+  position: fixed;
23
+  bottom: 0;
24
+  left: 0;
25
+  width:100%;
26
+}
27
+
28
+.image01002 {
29
+  width: 576rpx;
30
+  height: 443rpx;
31
+}
32
+
33
+
34
+.image01003 {
35
+  width: 108rpx;
36
+  height: 101rpx;
37
+  position: fixed;
38
+  bottom: 129rpx;
39
+  right: 57rpx;
40
+}
41
+

+ 95 - 0
pages/main/index.js

@@ -0,0 +1,95 @@
1
+import common from '../../utils/util';
2
+import server from '../../utils/main';
3
+
4
+const app = getApp();
5
+
6
+Page({
7
+  data: {
8
+    Version: app.globalData.Version,
9
+    List: [
10
+      {
11
+        ImageUrl: "109.png",
12
+        Url: "./basicMain?type=a_z",
13
+      },
14
+      {
15
+        ImageUrl: "101.png",
16
+        Url: "./basicMain?type=basic",
17
+      },
18
+      {
19
+        ImageUrl: "102.png",
20
+        Url: "./basicMain?type=intermediate",
21
+      },
22
+      {
23
+        ImageUrl: "103.png",
24
+        Url: "./basicMain?type=all",
25
+      },
26
+      {
27
+        ImageUrl: "107.png",
28
+        Url: "./basicMain?type=read",
29
+      },
30
+    ],
31
+    ListProgram: [
32
+      {
33
+        ImageUrl: "03001.png",
34
+        ImageUrl2: "02018.png",
35
+        appId: 'wx46a7b4c420e6d38f',
36
+        path: 'pages/index/start?SourceID=106',
37
+      },
38
+      {
39
+        ImageUrl: "03002.png",
40
+        ImageUrl2: "02020.png",
41
+        appId: 'wxb54a6d5aff836ee3',
42
+        path: 'pages/index/index?SourceID=106',
43
+      },
44
+      {
45
+        ImageUrl: "03003.png",
46
+        ImageUrl2: "02019.png",
47
+        appId: 'wx331e8dd070f01d0e',
48
+        path: 'pages/index/index?SourceID=106',
49
+      },
50
+      {
51
+        ImageUrl: "03004.png",
52
+        ImageUrl2: "02021.png",
53
+        appId: 'wxa5e33c61fe37dd01',
54
+        path: 'pages/index/index?SourceID=106',
55
+      },
56
+    ],
57
+    NickName: "陌生用户",
58
+    IsMember: false,
59
+    AvatarUrl: "",
60
+    DayNumber: "0",
61
+    ReviewCount: "0",
62
+    FinishedCount: "0",
63
+    IsAccredit: false,
64
+    NavClass1: "",
65
+    NavClass2: "nav2",
66
+    IsRemind: false,
67
+  },
68
+  onReady: function (e) {
69
+  },
70
+  onLoad: function () {
71
+    this.setData({
72
+      Height: common.getSystemHeight(),
73
+      indexImage: common.random(0, 2),
74
+    });
75
+  },
76
+  selectNav: function (e) {
77
+    var id = e.currentTarget.dataset.id;
78
+    //console.log(id);
79
+    if (id == "1") {
80
+      this.setData({
81
+        NavClass1: "",
82
+        NavClass2: "nav2",
83
+      })
84
+    }
85
+    else if (id == "2") {
86
+      this.setData({
87
+        NavClass1: "nav2",
88
+        NavClass2: "nav3",
89
+        IsRemind: false,
90
+      })
91
+      wx.setStorageSync('IsRemind', false);
92
+
93
+    }
94
+  },
95
+})

+ 4 - 0
pages/main/index.json

@@ -0,0 +1,4 @@
1
+{
2
+  "navigationBarTitleText": "课程",
3
+  "enablePullDownRefresh": false
4
+}

+ 152 - 0
pages/main/index.wxml

@@ -0,0 +1,152 @@
1
+<view class="container FlexColumn" style='min-height:{{Height}}rpx;'>
2
+  <view class="index1 FlexRow">
3
+    <view class="{{NavClass1}} nav FlexColumn" bindtap='selectNav' data-id="1">
4
+      <image src='../../images/02003.png' class="img3" />
5
+    </view>
6
+    <image src='../../images/02001.png' class="img" />
7
+    <view class="{{NavClass2}} nav FlexColumn" bindtap='selectNav' data-id="2">
8
+      <image src='../../images/02002.png' class="img2" />
9
+    </view>
10
+    <image src='../../images/02004.gif' class="hand" wx:if="{{IsRemind}}" bindtap='selectNav' data-id="2" />
11
+  </view>
12
+  <block wx:if="{{NavClass2=='nav2'}}">
13
+    <view class="index2 FlexRow">
14
+      <view class="index2_1 FlexRow">
15
+        <view class="btn" bindtap="">
16
+          <view class="btn1">
17
+            <view class="panel1 FlexRow">
18
+              <image src='../../images/02005.png' class="img" />
19
+            </view>
20
+            <view class="panel2 FlexRow">
21
+              <image src='../../images/02009.png' class="img2" />
22
+            </view>
23
+          </view>
24
+        </view>
25
+        <view class="btn" bindtap="">
26
+          <view class="btn1">
27
+            <view class="panel1 FlexRow">
28
+              <image src='../../images/02006.png' class="img" />
29
+            </view>
30
+            <view class="panel2 FlexRow">
31
+              <image src='../../images/02010.png' class="img2" />
32
+            </view>
33
+          </view>
34
+        </view>
35
+        <view class="btn" bindtap="">
36
+          <view class="btn1">
37
+            <view class="panel1 FlexRow">
38
+              <image src='../../images/02007.png' class="img" />
39
+            </view>
40
+            <view class="panel2 FlexRow">
41
+              <image src='../../images/02011.png' class="img2" />
42
+            </view>
43
+          </view>
44
+        </view>
45
+        <view class="btn" bindtap="">
46
+          <view class="btn1">
47
+            <view class="panel1 FlexRow">
48
+              <image src='../../images/02008.png' class="img" />
49
+            </view>
50
+            <view class="panel2 FlexRow">
51
+              <image src='../../images/02012.png' class="img2" />
52
+            </view>
53
+          </view>
54
+        </view>
55
+      </view>
56
+    </view>
57
+    <view class="index7 FlexRow">
58
+      <image src='../../images/02017.png' class="imgWave" />
59
+    </view>
60
+    <view class="index8 FlexColumn">
61
+      <image src='../../images/02013.png' class="img" />
62
+      <view class="index8_1">
63
+        搜一搜,输入一个字
64
+      </view>
65
+    </view>
66
+
67
+    <view class="index3 FlexColumn">
68
+      <image src='{{AvatarUrl}}' class="Avatar" bindtap="getAccredit" />
69
+      <view class="NickName">{{NickName}}</view>
70
+      <view class="Member2 Member" wx:if="{{!IsMember}}">非会员</view>
71
+      <view class="Member" wx:if="{{IsMember}}">付费会员</view>
72
+      <view class="index3_0 FlexRow">
73
+        <view class="index3_1 FlexColumn">
74
+          <view class="index3_1_1 FlexRow">
75
+            <view class="number" wx:if="{{!IsAccredit}}">-</view>
76
+            <view class="number" wx:if="{{IsAccredit}}">{{DayNumber}}</view>
77
+          </view>
78
+          <view class="index3_1_2 FlexRow">持续天数
79
+          </view>
80
+        </view>
81
+
82
+        <view class="index3_1 FlexColumn">
83
+          <view class="index3_1_1 FlexRow">
84
+            <view class="number" wx:if="{{!IsAccredit}}">-</view>
85
+            <view class="number" wx:if="{{IsAccredit}}">{{FinishedCount}}</view>
86
+          </view>
87
+          <view class="index3_1_2 FlexRow">已学章节
88
+          </view>
89
+        </view>
90
+        <view class="index3_1 FlexColumn">
91
+          <view class="index3_1_1 FlexRow">
92
+            <view class="number" wx:if="{{!IsAccredit}}">-</view>
93
+            <view class="number" wx:if="{{IsAccredit}}">{{PhonicsNumber}}</view>
94
+          </view>
95
+          <view class="index3_1_2 FlexRow">总共识字
96
+          </view>
97
+        </view>
98
+      </view>
99
+      <view class="btn2 btn" wx:if="{{!IsAccredit}}" bindtap="getAccredit">
100
+        <view class="btn1">开启统计</view>
101
+      </view>
102
+
103
+      <view class="btn5 btn3 btn" wx:if="{{ReviewCount==0}}">
104
+        <view class="btn4 btn1">复习</view>
105
+      </view>
106
+      <view class="btn8 btn6 btn" wx:if="{{ReviewCount>0}}" bindtap="gotoReview">
107
+        <view class="btn7 btn1"> 复习
108
+          <view class="ReviewCount">{{ReviewCount}}</view>
109
+        </view>
110
+      </view>
111
+
112
+      <button class="Circle FlexColumn" open-type="share">
113
+        <image src='../../images/02015.png' class="Share" />
114
+        <view class="">分享</view>
115
+      </button>
116
+
117
+    </view>
118
+
119
+    <view class="index9 FlexRow">
120
+      <image src='../../images/02016.png' class="imgWave" />
121
+    </view>
122
+  </block>
123
+  
124
+  <block wx:if="{{NavClass1=='nav2'}}">
125
+    <view class="index6 FlexColumn">
126
+      <image src='../../images/{{item.ImageUrl}}' class="btn2" wx:for="{{ListProgram}}" wx:key="index" bindtap='switchProgram' data-appid='{{item.appId}}' data-path='{{item.path}}' />
127
+    </view>
128
+  </block>
129
+
130
+  <view class="index5 FlexColumn">
131
+
132
+    <view class="FooterDescription_1">©2014-2018 语文识字 - 小学生素质练习系列产品</view>
133
+    <view class="FooterDescription_2" bindtap='updateMember'>微信小程序 版本 {{Version}} </view>
134
+    <view class="index5_1 FlexRow">
135
+      <button class="feedback" open-type="contact">
136
+        <view class="index5_1_1">意见反馈</view>
137
+      </button>
138
+      <view class="line"></view>
139
+      <view class="feedback1 feedback" bindtap='gotoAbout'>关联您的公众号</view>
140
+      <view class="line"></view>
141
+      <view class="feedback" bindtap='gotoAbout'>业务合作</view>
142
+    </view>
143
+    <view class="index5_2">唱意教育旗下产品
144
+    </view>
145
+    <view class="index5_3 FlexRow">
146
+      <image src='../../images/{{item.ImageUrl2}}' class="btn" wx:for="{{ListProgram}}" wx:key="index" bindtap='switchProgram' data-appid='{{item.appId}}' data-path='{{item.path}}' />
147
+
148
+    </view>
149
+
150
+  </view>
151
+
152
+</view>

+ 393 - 0
pages/main/index.wxss

@@ -0,0 +1,393 @@
1
+.container {
2
+  background-color: #F5E2BE;
3
+  justify-content: flex-start;
4
+  font-weight: 500;
5
+  color:#1e1e1e;
6
+}
7
+
8
+.index1{
9
+  width:100%;
10
+  height:190rpx;
11
+  justify-content: space-between;
12
+  align-items: flex-end;
13
+}
14
+
15
+.index1 .nav{
16
+  border-bottom: 10rpx solid #593613;
17
+  width:250rpx;
18
+  height: 80rpx;
19
+  padding-bottom: 10rpx;
20
+  justify-content: flex-end;
21
+}
22
+
23
+.index1 .nav2{
24
+  border-bottom: 10rpx solid #F5E2BE;
25
+}
26
+
27
+.index1 .nav3{
28
+  border-bottom: 10rpx solid #0C5F73;
29
+}
30
+
31
+.index1 .img{
32
+  width:174rpx;
33
+  height:190rpx;
34
+}
35
+.index1 .img3{
36
+  width:158rpx;
37
+  height:37rpx;
38
+  margin-bottom: 6rpx;
39
+}
40
+.index1 .img2{
41
+  width:154rpx;
42
+  height:39rpx;
43
+  margin-bottom: 6rpx;
44
+}
45
+.index1 .hand{
46
+  width:60rpx;
47
+  height:90rpx;
48
+  position: absolute;
49
+  right:106rpx;
50
+  top:20rpx;
51
+}
52
+
53
+.index6{
54
+  width:100%;
55
+  justify-content: flex-start;
56
+  flex-wrap: wrap;
57
+}
58
+
59
+.index6 .btn2{
60
+  width:100%;
61
+  height:350rpx;
62
+}
63
+
64
+.index2{
65
+  width:100%;
66
+  height:1038rpx;
67
+  background-color: #DFC7A4;
68
+  justify-content: flex-start;
69
+}
70
+
71
+.index2 .index2_1{
72
+  margin: 0 30rpx 0 30rpx;
73
+  width:690rpx;
74
+  flex-wrap: wrap;
75
+  justify-content: space-between;
76
+}
77
+.index2 .btn {
78
+  width: 330rpx;
79
+  height: 448rpx;
80
+  background-color: #CDB797;
81
+  border-radius: 20rpx;
82
+  margin-bottom: 20rpx;
83
+}
84
+.index2 .btn1 {
85
+  width: 100%;
86
+  height: 428rpx;
87
+  background-color: #F8F8F8;
88
+  border-radius: 20rpx;
89
+  position:relative;
90
+  top:0;
91
+}
92
+
93
+.index2 .panel1 {
94
+  width: 100%;
95
+  height: 298rpx;
96
+  border-bottom:2rpx solid #DFDFDF;
97
+}
98
+
99
+.index2 .panel2 {
100
+  width: 100%;
101
+  height: 130rpx;
102
+  background-color: #F0F0F0;
103
+  border-bottom-left-radius: 20rpx;
104
+  border-bottom-right-radius: 20rpx;
105
+}
106
+
107
+.index2 .img {
108
+  width: 223rpx;
109
+  height: 202rpx;
110
+}
111
+.index2 .img2 {
112
+  width: 217rpx;
113
+  height: 71rpx;
114
+}
115
+
116
+
117
+.index7{
118
+  width:100%;
119
+  height:35rpx;
120
+  background-color: #DFC7A4;
121
+  
122
+}
123
+.imgWave {
124
+  width: 100%;
125
+  height: 35rpx;
126
+}
127
+
128
+.index8{
129
+  width:100%;
130
+  height:406rpx;
131
+  background-color: #CDB797;
132
+  justify-content: flex-start;
133
+}
134
+
135
+.index8 .img{
136
+  width:314rpx;
137
+  height:39rpx;
138
+  margin-top: 102rpx;
139
+}
140
+
141
+.index8 .index8_1{
142
+  width:690rpx;
143
+  height:120rpx;
144
+  margin-top: 30rpx;
145
+  border-radius: 20rpx;
146
+  text-align: center;
147
+  line-height: 120rpx;
148
+  font-size:32rpx;
149
+  color:#1e1e1e;
150
+  background-color: #F0F0F0;
151
+}
152
+
153
+
154
+.index3{
155
+  width:100%;
156
+  justify-content: flex-start;
157
+  background-color: #F0F0F0;
158
+  align-items: center;
159
+  position: relative;
160
+  color:#1E1E1E;
161
+}
162
+
163
+.index3 .Avatar{
164
+  width:160rpx;
165
+  height:160rpx;
166
+  background-color: #9B9B9B;
167
+  border-radius: 20rpx;
168
+  margin-top: 120rpx;
169
+}
170
+
171
+.index3 .NickName{
172
+  font-size:48rpx;
173
+  color:#1E1E1E;
174
+  margin-top: 40rpx;
175
+  width:90%;
176
+  text-align: center;
177
+}
178
+
179
+.index3 .Member{
180
+  font-size:24rpx;
181
+  color:#fff;
182
+  background-color: #C29F6D;
183
+  border-radius: 8rpx;
184
+  height:42rpx;
185
+  line-height: 42rpx;
186
+  text-align: center;
187
+  padding: 0 10rpx;
188
+  margin-top: 10rpx;
189
+}
190
+
191
+.index3 .Member2{
192
+  background-color: #4A4A4A;
193
+}
194
+
195
+.index3 .index3_0{
196
+  width:100%;
197
+  margin-top: 50rpx;
198
+  justify-content: center;
199
+}
200
+.index3 .index3_1{
201
+  width:216rpx;
202
+  justify-content: center;
203
+}
204
+
205
+.index3 .index3_1_2{
206
+  width:116rpx;
207
+  height:42rpx;
208
+  text-align: center;
209
+  line-height: 42rpx;
210
+  color:#1E1E1E;
211
+  font-size:26rpx;
212
+}
213
+.index3 .number{
214
+  font-family: 'SF UI Display Light';
215
+  font-weight: 200;
216
+  font-style: normal;
217
+  font-size:56rpx;
218
+}
219
+.index3 .text{
220
+  font-size:24rpx;
221
+  margin: 25rpx 0 0 10rpx;
222
+}
223
+.index3 .Circle{
224
+  width:160rpx;
225
+  height:160rpx;
226
+  background-color: #ffffff;
227
+  border-radius: 50%;
228
+  margin-top: 100rpx;
229
+  padding-left: 0;
230
+  padding-right: 0;
231
+  margin-bottom: 80rpx;
232
+  font-size:24rpx;
233
+  justify-content: flex-start;
234
+}
235
+
236
+.index3 .Circle::after {
237
+  border: 0px;
238
+}
239
+
240
+.index3 .Share{
241
+  width:50rpx;
242
+  height:50rpx;
243
+  margin: 39rpx 0 0rpx 0;
244
+}
245
+
246
+.index3 .btn {
247
+  width: 600rpx;
248
+  height: 100rpx;
249
+  background-color: #035834;
250
+  border-radius: 14rpx;
251
+}
252
+.index3 .btn1 {
253
+  width: 100%;
254
+  height: 90rpx;
255
+  background-color: #03AF69;
256
+  border-radius: 14rpx;
257
+  color:#fff;
258
+  text-align: center;
259
+  line-height: 90rpx;
260
+  font-size:36rpx;
261
+  position:relative;
262
+  top:0;
263
+}
264
+
265
+.index3 .btn2 {
266
+  margin-top: 60rpx;
267
+}
268
+
269
+.index3 .btn3 {
270
+  background-color: #262626;
271
+}
272
+
273
+.index3 .btn4 {
274
+  background-color: #4D4D4D;
275
+  color:#787878;
276
+}
277
+
278
+.index3 .btn5 {
279
+  margin-top: 40rpx;
280
+}
281
+
282
+
283
+.index3 .btn6 {
284
+  background-color: #A63917;
285
+}
286
+
287
+.index3 .btn7 {
288
+  background-color: #FF7245;
289
+  position: relative;
290
+}
291
+
292
+.index3 .btn8 {
293
+  margin-top: 50rpx;
294
+}
295
+
296
+.index3 .ReviewCount {
297
+  min-width: 53rpx;
298
+  height:50rpx;
299
+  background-color: #D54F24;
300
+  color:#fff;
301
+  border-radius: 8rpx;
302
+  text-align: center;
303
+  line-height: 50rpx;
304
+  position: absolute;
305
+  right: 20rpx;
306
+  top: 20rpx;
307
+  font-size:24rpx;
308
+  font-family: 'Arial BoldMT';
309
+  font-weight: bold;
310
+  font-style: normal;
311
+}
312
+
313
+
314
+.index9{
315
+  width:100%;
316
+  height:35rpx;
317
+  background-color: #F0F0F0;
318
+  
319
+}
320
+
321
+.index4{
322
+  width:100%;
323
+  height:10rpx;
324
+  background-color: #EB8A95;
325
+}
326
+
327
+.index5{
328
+  width:100%;
329
+  height:628rpx;
330
+  background-color: #F5E2BE;
331
+  font-size:20rpx;
332
+  justify-content: flex-start;
333
+  color:#1e1e1e;
334
+}
335
+
336
+
337
+.FooterDescription_1{
338
+  margin-top: 60rpx;
339
+}
340
+
341
+
342
+.index5 .index5_1{
343
+  width:100%;
344
+  justify-content: center;
345
+}
346
+
347
+
348
+.index5 .feedback {
349
+  padding-left: 0;
350
+  padding-right: 0;
351
+  width:156rpx;
352
+  height:93rpx;
353
+  background-color: #F5E2BE;
354
+  margin: 30rpx 0rpx;
355
+  text-align: center;
356
+  line-height: 93rpx;
357
+  font-size:24rpx;
358
+}
359
+
360
+.index5 .feedback1 {
361
+  width:228rpx;
362
+}
363
+
364
+.index5 .index5_1_1{
365
+  color:#1e1e1e;
366
+}
367
+
368
+.index5 .feedback::after {
369
+  border: 0px;
370
+}
371
+
372
+.index5 .line {
373
+  width:5rpx;
374
+  height:20rpx;
375
+  background-color: #CDB797;
376
+}
377
+
378
+.index5 .index5_2{
379
+   font-size:24rpx;
380
+}
381
+.index5 .index5_3{
382
+  margin-top: 30rpx;
383
+  width:630rpx;
384
+   flex-wrap: wrap;
385
+   justify-content: space-between;
386
+}
387
+
388
+
389
+.index5 .btn {
390
+  width:300rpx;
391
+  height:88rpx;
392
+  margin-bottom: 20rpx;
393
+}

+ 36 - 0
pages/main/list.js

@@ -0,0 +1,36 @@
1
+import common from '../../utils/util';
2
+import server from '../../utils/main';
3
+
4
+const app = getApp();
5
+
6
+Page({
7
+  data: {
8
+  
9
+  },
10
+  onLoad: function (options) {
11
+    this.setData({
12
+      Height: common.getSystemHeight(),
13
+      NavClass1: "nav1",
14
+      NavClass2: "nav2",
15
+      IsShowNav1:true,
16
+    });
17
+  },
18
+  selectNav: function (e) {
19
+    var id = e.currentTarget.dataset.id;
20
+    //console.log(id);
21
+    if (id == "1") {
22
+      this.setData({
23
+        NavClass1: "nav1",
24
+        NavClass2: "nav2",
25
+        IsShowNav1:true,
26
+      })
27
+    }
28
+    else if (id == "2") {
29
+      this.setData({
30
+        NavClass1: "nav2",
31
+        NavClass2: "nav1",
32
+        IsShowNav1: false,
33
+      })
34
+    }
35
+  },
36
+})

+ 5 - 0
pages/main/list.json

@@ -0,0 +1,5 @@
1
+{
2
+  "navigationBarBackgroundColor": "#f0f0f0",
3
+  "navigationBarTitleText": "",
4
+  "enablePullDownRefresh": false
5
+}

+ 101 - 0
pages/main/list.wxml

@@ -0,0 +1,101 @@
1
+<view class="container FlexColumn" style='min-height:{{Height}}rpx;'>
2
+  <view class="line"></view>
3
+  <view class="line1 line"></view>
4
+  <image src='../../images/04001.png' class="topImage" />
5
+
6
+  <view class="line"></view>
7
+
8
+  <view class="list1 FlexRow">
9
+    <view class="nav FlexColumn" bindtap='selectNav' data-id="1">
10
+      <view class='{{NavClass1}}'>课本</view>
11
+    </view>
12
+    <view class="nav FlexColumn" bindtap='selectNav' data-id="2">
13
+      <view class='{{NavClass2}}'>字表</view>
14
+    </view>
15
+  </view>
16
+
17
+  <block wx:if="{{IsShowNav1}}">
18
+    <view class="line2 line">
19
+    </view>
20
+    <view class="list2 FlexColumn">
21
+      <view class="btn" bindtap="">
22
+        <view class="btn1 FlexRow">
23
+          <view class="left FlexRow">
24
+            <image src='../../images/04007.png' class="img04007" />
25
+            <view class="title">天地人</view>
26
+          </view>
27
+          <view class="right FlexColumn">
28
+            <view class="right1 FlexRow">
29
+              <view class="line"></view>
30
+              <view class="title2">识字 1-5</view>
31
+            </view>
32
+            <view class="right2 FlexRow">
33
+              <image src='../../images/04008.png' class="img04008" />
34
+              <view class="title3">38个</view>
35
+            </view>
36
+          </view>
37
+        </view>
38
+      </view>
39
+      <view class="btn" bindtap="">
40
+        <view class="btn1 FlexRow">
41
+          <view class="left FlexRow">
42
+            <image src='../../images/04005.png' class="img04005" />
43
+            <view class="title">爸妈</view>
44
+          </view>
45
+          <view class="right FlexColumn">
46
+            <view class="right1 FlexRow">
47
+              <view class="line"></view>
48
+              <view class="title2">汉语拼音 1-8</view>
49
+            </view>
50
+            <view class="right2 FlexRow">
51
+              <image src='../../images/04008.png' class="img04008" />
52
+              <view class="title3">38个</view>
53
+            </view>
54
+          </view>
55
+        </view>
56
+      </view>
57
+      <view class="btn" bindtap="">
58
+        <view class="btn1 FlexRow">
59
+          <view class="left FlexRow">
60
+            <image src='../../images/04006.png' class="img04007" />
61
+            <view class="title">秋叶飞</view>
62
+          </view>
63
+          <view class="right FlexColumn">
64
+            <view class="right1 FlexRow">
65
+              <view class="line"></view>
66
+              <view class="title2">汉语拼音 9-10</view>
67
+            </view>
68
+            <view class="right2 FlexRow">
69
+              <image src='../../images/04008.png' class="img04008" />
70
+              <view class="title3">38个</view>
71
+            </view>
72
+          </view>
73
+        </view>
74
+      </view>
75
+    </view>
76
+    <view class="line3 line">
77
+  </view>
78
+  </block>
79
+
80
+  <block wx:if="{{!IsShowNav1}}">
81
+    <view class="group FlexColumn">
82
+      <view class="title FlexRow">
83
+        <view class="title1">识字1-5</view>
84
+      </view>
85
+      <view class="table FlexRow">
86
+      <view class="boxSelect box" wx:for="{{['中','中','中','中','中','中','中','中','中']}}">{{item}}</view>
87
+      </view>
88
+    </view>
89
+    <view class="group FlexColumn">
90
+      <view class="title FlexRow">
91
+        <view class="title1">识字1-5</view>
92
+      </view>
93
+      <view class="table FlexRow">
94
+      <view class="box" wx:for="{{['中','中','中','中','中','中','中','中','中']}}">{{item}}</view>
95
+      </view>
96
+    </view>
97
+    <view class="line4 line">
98
+  </view>
99
+  </block>
100
+  
101
+</view>

+ 166 - 0
pages/main/list.wxss

@@ -0,0 +1,166 @@
1
+.container {
2
+  background-color: #dfc7a4;
3
+  justify-content: flex-start;
4
+  font-weight: 500;
5
+  color: #1e1e1e;
6
+}
7
+
8
+.line {
9
+  width: 100%;
10
+  height: 10rpx;
11
+  background-color: #593613;
12
+}
13
+
14
+.line1 {
15
+  background-color: #c4a271;
16
+}
17
+
18
+.topImage {
19
+  width: 100%;
20
+  height: 430rpx;
21
+}
22
+
23
+.list1 {
24
+  width: 100%;
25
+  height: 100rpx;
26
+  background-color: #c4a270;
27
+  font-size: 36rpx;
28
+}
29
+
30
+.list1 .nav {
31
+  width: 50%;
32
+  height: 100rpx;
33
+  justify-content: flex-end;
34
+}
35
+
36
+.list1 .nav1 {
37
+  border-bottom: 10rpx solid #593613;
38
+  line-height: 70rpx;
39
+}
40
+
41
+.list1 .nav2 {
42
+  border-bottom: 10rpx solid #c4a270;
43
+  line-height: 70rpx;
44
+}
45
+
46
+.list2 {
47
+  width: 100%;
48
+  background-color: #dfc7a4;
49
+  font-size: 36rpx;
50
+}
51
+
52
+.list2 .btn {
53
+  width: 690rpx;
54
+  height: 192rpx;
55
+  background-color: #CDB797;
56
+  border-radius: 10rpx;
57
+  margin-bottom: 20rpx;
58
+}
59
+
60
+.list2 .btn1 {
61
+  width: 100%;
62
+  height: 180rpx;
63
+  background-color: #F0F0F0;
64
+  border-radius: 10rpx;
65
+  position: relative;
66
+  top: 0;
67
+  justify-content: space-between;
68
+}
69
+
70
+.list2 .left {
71
+  margin-left: 40rpx;
72
+}
73
+
74
+.list2 .right {
75
+  margin-right: 40rpx;
76
+  align-items: flex-end;
77
+}
78
+
79
+.list2 .right1 {
80
+  margin-bottom: 10rpx;
81
+}
82
+
83
+.list2 .img04005 {
84
+  width:24rpx;
85
+  height:30rpx;
86
+}
87
+.list2 .img04007 {
88
+  width:24rpx;
89
+  height:39rpx;
90
+}
91
+.list2 .img04008 {
92
+  width:30rpx;
93
+  height:30rpx;
94
+}
95
+
96
+.list2 .title {
97
+  margin-left: 30rpx;
98
+  font-size:58rpx;
99
+}
100
+
101
+.list2 .line {
102
+  width:5rpx;
103
+  height:20rpx;
104
+  background-color: #DFC7A4;
105
+}
106
+
107
+.list2 .title2 {
108
+  font-size:22rpx;
109
+  margin-left: 30rpx;
110
+}
111
+.list2 .title3 {
112
+  font-size:20rpx;
113
+  margin-left: 10rpx;
114
+}
115
+
116
+.line2 {
117
+  background-color: #dfc7a4;
118
+  height:40rpx;
119
+}
120
+.line3 {
121
+  background-color: #dfc7a4;
122
+  height:100rpx;
123
+}
124
+.line4 {
125
+  background-color: #dfc7a4;
126
+  height:80rpx;
127
+}
128
+
129
+.group{
130
+  width:100%;
131
+  justify-content: flex-start;
132
+  background-color: #F5E2BE;
133
+  margin-bottom: 20rpx;
134
+}
135
+.group .title{
136
+  width:100%;
137
+  margin: 50rpx 0 0 0;
138
+  justify-content: flex-start;
139
+}
140
+.group .title1{
141
+  margin: 0 0 0 30rpx;
142
+  font-size:28rpx;
143
+}
144
+.group .table{
145
+  margin: 30rpx 24rpx 60rpx 30rpx;
146
+  font-size:48rpx;
147
+  justify-content: flex-start;
148
+  align-items: flex-start;
149
+  flex-wrap: wrap;
150
+}
151
+.group .box{
152
+  margin: 0 6rpx 6rpx 0;
153
+  background-color: #fff;
154
+  width:110rpx;
155
+  height:110rpx;
156
+  text-align: center;
157
+  line-height: 110rpx;
158
+  font-weight: 400;
159
+}
160
+.group .boxSelect{
161
+  color:#fff;
162
+  background-color: #FFA556;
163
+  border:1rpx solid #593613;
164
+  width:106rpx;
165
+  height:106rpx;
166
+}

+ 50 - 0
project.config.json

@@ -0,0 +1,50 @@
1
+{
2
+	"description": "项目配置文件。",
3
+	"setting": {
4
+		"urlCheck": true,
5
+		"es6": true,
6
+		"postcss": true,
7
+		"minified": true,
8
+		"newFeature": true
9
+	},
10
+	"compileType": "miniprogram",
11
+	"libVersion": "1.9.93",
12
+	"appid": "wx313a8f2c0741efe1",
13
+	"projectname": "%E8%AF%86%E5%AD%97",
14
+	"isGameTourist": false,
15
+	"condition": {
16
+		"search": {
17
+			"current": -1,
18
+			"list": []
19
+		},
20
+		"conversation": {
21
+			"current": -1,
22
+			"list": []
23
+		},
24
+		"plugin": {
25
+			"current": -1,
26
+			"list": []
27
+		},
28
+		"game": {
29
+			"currentL": -1,
30
+			"list": []
31
+		},
32
+		"miniprogram": {
33
+			"current": 1,
34
+			"list": [
35
+				{
36
+					"id": -1,
37
+					"name": "首页",
38
+					"pathName": "pages/main/index",
39
+					"query": ""
40
+				},
41
+				{
42
+					"id": -1,
43
+					"name": "列表",
44
+					"pathName": "pages/main/list",
45
+					"query": ""
46
+				}
47
+			]
48
+		}
49
+	}
50
+}

+ 19 - 0
utils/cryptojs.js

@@ -0,0 +1,19 @@
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
+});
18
+
19
+

+ 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
+})();

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 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
+})();

+ 127 - 0
utils/main.js

@@ -0,0 +1,127 @@
1
+import common from './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 payMoney(payType, money, callback) {
71
+  console.log(money);
72
+  if (app.globalData.userInfo.UserID == 1)
73
+    money = 0.01;
74
+  //登录认证
75
+  wx.login({
76
+    success: function (res) {
77
+      if (res.code) {
78
+        console.log('获取用户登录态成功!' + res.code);
79
+        //预支付
80
+        getData('PhonicsPayLogin?code=' + res.code + '&payType=' + payType + '&money=' + money, function (data) {
81
+          if (data && data.timeStamp) {
82
+            //微信支付
83
+            wx.requestPayment({
84
+              'timeStamp': data.timeStamp.toString(),
85
+              'nonceStr': data.nonceStr,
86
+              'package': data.package,
87
+              'signType': 'MD5',
88
+              'paySign': data.paySign,
89
+              'success': function (res3) {
90
+                app.globalData.userInfo.IsMember = 1;
91
+                app.globalData.userInfo.IsPay = 1;
92
+                console.log("success:" + res3);
93
+                callback();
94
+              },
95
+              'fail': function (err) {
96
+                if (err && err.errMsg && err.errMsg.indexOf("fail cancel")) {
97
+
98
+                }
99
+                else {
100
+                  wx.showToast({
101
+                    title: '服务器忙,请稍候再试!',
102
+                    duration: 3000
103
+                  });
104
+                }
105
+              }
106
+            });
107
+          }
108
+        });
109
+
110
+      } else {
111
+        console.log('获取用户登录态失败!' + res.errMsg);
112
+        wx.showToast({
113
+          title: '服务器忙,请稍候再试!',
114
+          duration: 3000
115
+        });
116
+      }
117
+    }
118
+  });
119
+}
120
+
121
+
122
+module.exports = {
123
+  getData: getData,
124
+  postData: postData,
125
+  payMoney: payMoney,
126
+  getLocalHost: getLocalHost,
127
+}

+ 413 - 0
utils/util.js

@@ -0,0 +1,413 @@
1
+var Crypto = require('cryptojs.js').Crypto;
2
+var app = getApp();
3
+
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(':')
15
+}
16
+
17
+function formatDateCHS(date) {
18
+  date = date.toString();
19
+  var year = date.substr(0, 4);
20
+  var month = date.substr(5, 2);
21
+  var day = date.substr(8, 2);
22
+
23
+  return year + "年" + month + "月" + day + "日";
24
+}
25
+
26
+
27
+function getTimeFormat(duration) {
28
+  //console.log("duration:" + duration);
29
+  var arr = ['', '', '']
30
+  if (duration.indexOf("'") > 0)
31
+    arr[0] = duration.substring(0, duration.indexOf("'"));
32
+  if (duration.indexOf(".") > 0) {
33
+    arr[1] = duration.substring(duration.indexOf("'") + 1, duration.indexOf(".") + 1);
34
+    arr[2] = duration.substring(duration.indexOf(".") + 1, duration.indexOf('"'));
35
+  }
36
+  else {
37
+    arr[1] = duration.substring(duration.indexOf("'") + 1, duration.indexOf('"'));
38
+  }
39
+  return arr;
40
+}
41
+
42
+function formatNumber(n) {
43
+  n = n.toString()
44
+  return n[1] ? n : '0' + n
45
+}
46
+
47
+//给字符串左侧补零
48
+function addZero(str, length) {
49
+  while (str.length < length) {
50
+    str = "0" + str;
51
+  }
52
+  return str;
53
+}
54
+
55
+function getMinuteSecond(second, chs) {
56
+  var secondUnit = "\"";
57
+  var minuteUnit = "'";
58
+  var hourUnit = ":";
59
+  if (chs) {
60
+    secondUnit = "秒";
61
+    minuteUnit = "分钟";
62
+    hourUnit = "小时";
63
+    second = Math.round(second);
64
+  }
65
+  if (second < 60)
66
+    return second + secondUnit;
67
+  else {
68
+    var minute = Math.floor(second / 60);
69
+    second = Math.round((second - minute * 60) * 1000) / 1000;
70
+
71
+    if (minute >= 60) {
72
+      var hour = Math.floor(minute / 60);
73
+      minute = minute - hour * 60;
74
+
75
+      if (minute == 0 && second == 0)
76
+        return hour + hourUnit;
77
+      else if (second == 0)
78
+        return hour + hourUnit + minute + minuteUnit;
79
+      else
80
+        return hour + hourUnit + minute + minuteUnit + second + secondUnit;
81
+    }
82
+    else {
83
+      if (second == 0)
84
+        return minute + minuteUnit;
85
+      else
86
+        return minute + minuteUnit + second + secondUnit;
87
+    }
88
+  }
89
+}
90
+
91
+function Random(start, end) {
92
+  var result = parseInt(Math.random() * (end - start + 1) + start);
93
+  return result;
94
+}
95
+//打乱数组
96
+function RandomArray(arr) {
97
+  var arrResult = [];
98
+  var maxCount = 0;
99
+  do {
100
+    var rnd = Random(0, arr.length - 1);
101
+    if (arr[rnd]) {
102
+      arrResult.push(arr[rnd]);
103
+      arr[rnd] = null;
104
+    }
105
+    maxCount++;
106
+  }
107
+  while (arrResult.length < arr.length && maxCount < 1000);
108
+  return arrResult;
109
+}
110
+
111
+function Unique(arr) {
112
+  var res = [];
113
+  var json = {};
114
+  for (var i = 0; i < arr.length; i++) {
115
+    if (!json[arr[i]]) {
116
+      res.push(arr[i]);
117
+      json[arr[i]] = 1;
118
+    }
119
+  }
120
+  return res;
121
+}
122
+
123
+function getEnumerationName(id, list) {
124
+  for (var i = 0; i < list.length; i++) {
125
+    if (id == list[i].EnumID) {
126
+      return list[i].Name;
127
+    }
128
+  }
129
+  return "";
130
+}
131
+
132
+function getEnumerationNameByDescription(description, list) {
133
+  for (var i = 0; i < list.length; i++) {
134
+    if (description == list[i].Description) {
135
+      return list[i].Name;
136
+    }
137
+  }
138
+  return "";
139
+}
140
+
141
+function getStringMaxLength(str, len) {
142
+  if (str.length > len)
143
+    return str.substr(0, len) + "...";
144
+  else
145
+    return str;
146
+}
147
+
148
+function sort(array, sort_order, obj, objType, obj2, objType2) {
149
+  for (var i = 0; i < array.length - 1; i++) {
150
+    for (var j = i + 1; j < array.length; j++) {
151
+      var check;
152
+      if (objType == "Number") {
153
+        if (sort_order == "ASC")
154
+          check = array[i][obj] < array[j][obj];
155
+        else
156
+          check = array[i][obj] > array[j][obj];
157
+      }
158
+      else {
159
+        //console.log("array["+i+"]:"+array[i][obj]);
160
+        //console.log("array["+j+"]:"+array[j][obj]);
161
+        if (array[i][obj] && array[j][obj]) {
162
+          try {
163
+            if (sort_order == "ASC")
164
+              check = array[i][obj].toString().localeCompare(array[j][obj].toString()) >= 0;
165
+            else if (sort_order == "DESC")
166
+              check = array[i][obj].toString().localeCompare(array[j][obj].toString()) < 0;
167
+          }
168
+          catch (ex) {
169
+            console.log("ex:" + ex);
170
+            if (sort_order == "ASC")
171
+              check = array[i][obj].toString() >= array[j][obj].toString();
172
+            else if (sort_order == "DESC")
173
+              check = array[i][obj].toString() < array[j][obj].toString();
174
+
175
+          }
176
+        }
177
+        else {
178
+          check = false;
179
+        }
180
+      }
181
+      if (check) {
182
+        var temp = swap(array[i], array[j]);
183
+        array[i] = temp.a;
184
+        array[j] = temp.b;
185
+      }
186
+    }
187
+  }
188
+  return array;
189
+
190
+  function swap(a, b) {
191
+    var tempA = JSON.stringify(a);
192
+    var tempB = JSON.stringify(b);
193
+    return {
194
+      a: JSON.parse(tempB),
195
+      b: JSON.parse(tempA),
196
+    }
197
+  }
198
+}
199
+////测试sort
200
+// var a = [
201
+//   {
202
+//     time: "2017-2-1",
203
+//     a: 3,
204
+//   }, {
205
+//     time: "2017-4-1",
206
+//     a: 5,
207
+//   }, {
208
+//     time: "2017-1-1",
209
+//     a: 6
210
+//   },{
211
+//     time: "2017-2-1",
212
+//     a: 3
213
+//   },
214
+// ];
215
+// console.log(a);
216
+// // var a = common.sort(a,"ASC", "time","String");
217
+// // console.log(a);
218
+// var a = common.sort(a,"DESC", "time","String");
219
+// console.log(a);
220
+// //var a = common.sort(a,"DESC", "a","Number");
221
+// // console.log(a);
222
+
223
+function checkError(err) {
224
+  switch (err) {
225
+    case 404:
226
+    case 500:
227
+    case 501:
228
+    case 502:
229
+    case 503:
230
+    case 504:
231
+    case 505:
232
+      wx.navigateTo({
233
+        url: '../About/ErrorPage',
234
+        fail: function (e) {
235
+          wx.reLaunch({
236
+            url: '../index/start',
237
+          })
238
+        }
239
+      });
240
+      break;
241
+  }
242
+  return null;
243
+}
244
+
245
+function Encrypt(word) {
246
+  var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
247
+  var eb = Crypto.charenc.UTF8.stringToBytes(word);
248
+  var kb = Crypto.charenc.UTF8.stringToBytes(app.globalData.Key);//KEY
249
+  var vb = Crypto.charenc.UTF8.stringToBytes(app.globalData.IV);//IV
250
+  var ub = Crypto.AES.encrypt(eb, kb, { iv: vb, mode: mode, asBpytes: true });
251
+  return ub;
252
+}
253
+
254
+function Decrypt(word) {
255
+  var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
256
+  var eb = Crypto.util.base64ToBytes(word);
257
+  var kb = Crypto.charenc.UTF8.stringToBytes(app.globalData.Key);//KEY
258
+  var vb = Crypto.charenc.UTF8.stringToBytes(app.globalData.IV);//IV
259
+  var ub = Crypto.AES.decrypt(eb, kb, { asBpytes: true, mode: mode, iv: vb });
260
+  return ub;
261
+}
262
+
263
+function isExistStr(str1, str2) {
264
+  var result = false;
265
+  if (str1) {
266
+    if (str1.toString().indexOf(str2) >= 0) {
267
+      result = true;
268
+    }
269
+  }
270
+  return result;
271
+}
272
+
273
+
274
+function getSystemHeight() {
275
+  var systemInfo = wx.getSystemInfoSync();
276
+  var height = systemInfo.windowHeight;
277
+  if (systemInfo.model) {
278
+    if (height == 603 && systemInfo.model.indexOf("Plus") > 0) {
279
+      height = 625;
280
+    }
281
+    else if (height == 504 && (
282
+      systemInfo.model.indexOf("iPhone 6<") >= 0
283
+      || systemInfo.model.indexOf("iPhone 7<") >= 0
284
+      || systemInfo.model.indexOf("iPhone 6s<") >= 0
285
+      || systemInfo.model.indexOf("iPhone 5") >= 0
286
+      || systemInfo.model.indexOf("iPhone SE") >= 0
287
+    )) {
288
+      height = 596;
289
+    }
290
+  }
291
+
292
+  height = height * 2;
293
+  if (systemInfo.system && systemInfo.system.indexOf("Android") >= 0) {
294
+    height = height + 168;
295
+  }
296
+  return height;
297
+}
298
+
299
+//获取存储数据,若不存在,则获得缺省值。
300
+function getStorageValue(obj, name, defaultStatus, callback) {
301
+  wx.getStorage({
302
+    key: name,
303
+    success: function (res) {
304
+      obj.data[name] = res.data;
305
+      obj.setData(obj.data);
306
+      if (callback)
307
+        callback();
308
+    },
309
+    fail: function (res) {
310
+      obj.data[name] = defaultStatus;
311
+      obj.setData(obj.data);
312
+      if (callback)
313
+        callback();
314
+    },
315
+  });
316
+}
317
+
318
+//var arr=getWordArray("cakeface","a e");
319
+//console.log(arr);
320
+function getWordArray(word, key) {
321
+  var result = [];
322
+  word = word.toLowerCase();
323
+  if (key.length == 1) {
324
+    var number1 = word.indexOf(key);
325
+    result.push({ css: "", name: word.substr(0, number1) });
326
+    result.push({ css: "highlight", name: key });
327
+    result.push({ css: "", name: word.substr(number1 + 1) });
328
+  }
329
+  else {
330
+    if (key.indexOf(" ") >= 0) {
331
+      var arrKey = key.split(" ");
332
+      var number2 = word.lastIndexOf(arrKey[1]);
333
+      var number1 = word.lastIndexOf(arrKey[0], number2 - 2);
334
+      //console.log("number1:" + number1);
335
+      //console.log("number2:" + number2);
336
+
337
+      if (number1 + 2 != number2) {
338
+        number1 = word.indexOf(arrKey[0], number1 + 1);
339
+        number2 = word.indexOf(arrKey[1], number1 + 1);
340
+      }
341
+      result.push({ css: "", name: word.substr(0, number1) });
342
+      result.push({ css: "highlight", name: arrKey[0] });
343
+      result.push({ css: "", name: word.substr(number1 + 1, 1) });
344
+      result.push({ css: "highlight", name: arrKey[1] });
345
+      result.push({ css: "", name: word.substr(number2 + 1) });
346
+    }
347
+    else {
348
+      var number1 = word.indexOf(key);
349
+      var number2 = number1+key.length;
350
+      result.push({ css: "", name: word.substr(0, number1) });
351
+      result.push({ css: "highlight", name: key});
352
+      result.push({ css: "", name: word.substr(number2) });
353
+    }
354
+
355
+  }
356
+  return result;
357
+}
358
+
359
+//var arrTemp=["test","a","bdt","bca"];
360
+//console.log(sortArrayByStringLength(arrTemp));
361
+
362
+//排序数组根据字符串长度
363
+function sortArrayByStringLength(arr){
364
+  var result=[],temp=[];
365
+  for(var i=0;i<30;i++){
366
+    temp.push([]);
367
+  }
368
+  for (var i = 0; i < arr.length; i++) {
369
+    var item=arr[i];
370
+    temp[item.length].push(item);
371
+  }
372
+  for (var i = 0; i < temp.length; i++) {
373
+    temp[i].sort();
374
+    for (var j = 0; j < temp[i].length;j++){
375
+      result.push(temp[i][j]);
376
+    }
377
+  }
378
+  return result;
379
+}
380
+
381
+function ReplaceAllString(str, replaceStrFrom, replaceStrTo) {//替换
382
+  if (str && str.length > 0) {
383
+    var reg = new RegExp(replaceStrFrom, "g");
384
+    //console.log(str);
385
+    return str.toString().replace(reg, replaceStrTo);
386
+  }
387
+  else
388
+    return str;
389
+}
390
+
391
+module.exports = {
392
+  formatTime: formatTime,
393
+  formatDateCHS: formatDateCHS,
394
+  getMinuteSecond: getMinuteSecond,
395
+  random: Random,
396
+  randomArray: RandomArray,
397
+  unique: Unique,
398
+  getEnumerationName: getEnumerationName,
399
+  getStringMaxLength: getStringMaxLength,
400
+  sort: sort,
401
+  addZero: addZero,
402
+  checkError: checkError,
403
+  Encrypt: Encrypt,
404
+  Decrypt: Decrypt,
405
+  getEnumerationNameByDescription: getEnumerationNameByDescription,
406
+  isExistStr: isExistStr,
407
+  getSystemHeight: getSystemHeight,
408
+  getStorageValue: getStorageValue,
409
+  getTimeFormat: getTimeFormat,
410
+  getWordArray: getWordArray,
411
+  sortArrayByStringLength: sortArrayByStringLength,
412
+  ReplaceAllString: ReplaceAllString
413
+}