├── .gitignore ├── LICENSE ├── README.md ├── css ├── donationQR.gif └── visualPrivKey.css ├── favicon.ico ├── htaccess ├── index.html ├── info.txt ├── js ├── QRcode.js ├── bitcoinJS-lib.js └── visualPrivKeyMain.js └── robots.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Project structure 2 | # 1) index.html ---> main HTML file with the objects and references to scripts and styles 3 | # 2) css/visualPrivKey.css ---> Styles sheet 4 | # 3) js/visualPrivKeyMain.js ---> Main script with canvas calculations and object functions 5 | # 4) js/bitcoinJS-lib.js ---> BitcoinJS-lib v0.1.3-default (ECDSA formulas) 6 | # 5) js/QRcode.js ---> QR Code Generator for JavaScript 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 MrFreeDragon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VisualBTC 2 | Visual bitcoin private key generator. The square 16x16 is used for generation purposes, where each cell is one bit - 0 or 1. Make your visual drawings or use the generator in coin mode just fllipping the coin and fill the corresponding cell depending on the coin outcome. 3 | 4 | Project structure: 5 | 6 | 1) index.html ---> main HTML file with the objects and references to scripts and styles 7 | 2) css/visualPrivKey.css ---> Styles sheet 8 | 3) js/visualPrivKeyMain.js ---> Main script with canvas calculations and object functions 9 | 4) js/bitcoinJS-lib.js ---> BitcoinJS-lib v0.1.3-default (ECDSA formulas) 10 | 5) js/QRcode.js ---> QR Code Generator for JavaScript 11 | 12 | Project discussion: https://bitcointalk.org/index.php?topic=5187401.0 13 | 14 | This project represents the visual bitcoin private key generator. Please have a look at info.txt file for the description. 15 | 16 | The square 16x16 (=256) is used for generation purposes, where each cell represents one bit. The idea is that the filled cell represents "1" bit in the key, and not filled cell represents "0" bit in the key. Such presentation allows creating visual keys which could be easily memorized by human, but hardly understood by machines. 17 | You cann also safely create your bitcoin private key by flipping a coin 256 times. Just start flipping the coin and filling the cells line by line from 1x1 to 16x16 and after 256 outcomes you will have a nonsense "picture" represented your unique private key. You can be sure that nobody in the world have ever generated the same key or would generate in the future. 18 | 19 | (c) 2019 Visual Private Key Generator by MrFreeDragon > Donations: 1SoDn3auKHVwmQKRaBgkPk2hMmXzCMcPw 20 | 21 | https://btckeygen.com/ 22 | -------------------------------------------------------------------------------- /css/donationQR.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrFreeDragon/VisualBTC/3787b85b8b68202f413ee306ccfcdb318ace3858/css/donationQR.gif -------------------------------------------------------------------------------- /css/visualPrivKey.css: -------------------------------------------------------------------------------- 1 | .mainDIVcss { 2 | text-align:center; 3 | float:none; 4 | display:block; 5 | margin-left:20px; 6 | padding-bottom:30px; 7 | width:670px; 8 | } 9 | 10 | h1 { 11 | color: #FF8000; 12 | font-size: 30px; 13 | font-weight: bold; 14 | } 15 | 16 | h2 { 17 | font-size: 14px; 18 | font-weight: bold; 19 | } 20 | 21 | .textbox { 22 | border: 1px dotted #000000; 23 | outline:0; 24 | height:25px; 25 | width: 476px; 26 | padding-left: 5px; 27 | padding-right: 5px; 28 | margin-bottom: 20px; 29 | } 30 | 31 | .textboxOnlineResult { 32 | border: 1px dotted #000000; 33 | outline:0; 34 | display:none; 35 | height:25px; 36 | width: 90px; 37 | padding-left: 5px; 38 | padding-right: 5px; 39 | margin-bottom: 20px; 40 | } 41 | 42 | .textboxVis { 43 | border: 1px dotted #FF8000; 44 | outline:0; 45 | height:25px; 46 | width: 476px; 47 | padding-left: 5px; 48 | padding-right: 5px; 49 | margin-bottom: 20px; 50 | margin-top: 5px; 51 | display:inline-block 52 | } 53 | 54 | .textfield { 55 | border: 1px dotted #000000; 56 | outline:0; 57 | height:75px; 58 | width: 476px; 59 | padding-left: 5px; 60 | padding-right: 5px; 61 | } 62 | 63 | .TextDescr { 64 | border: 0px; 65 | border-radius: 13px; 66 | resize: none; 67 | outline:0; 68 | height:75px; 69 | width: 660px; 70 | padding-left: 5px; 71 | padding-right: 5px; 72 | background-color:#FDF4E3; 73 | overflow:hidden; 74 | color:black; 75 | } 76 | 77 | .TextWarn { 78 | border: 1px solid red; 79 | border-radius: 13px; 80 | resize: none; 81 | outline:0; 82 | height:60px; 83 | width: 660px; 84 | padding-left: 5px; 85 | padding-right: 5px; 86 | background-color:#FDF4E3; 87 | overflow:hidden; 88 | color:red; 89 | } 90 | 91 | .VisWarn { 92 | border: 1px solid orange; 93 | border-radius: 7px; 94 | resize: none; 95 | outline:0; 96 | height:30px; 97 | width: 560px; 98 | padding-left: 11px; 99 | padding-right: 11px; 100 | background-color:#FDF4E3; 101 | overflow:hidden; 102 | color:black; 103 | } 104 | 105 | .textfieldPK { 106 | border: 1px dotted #000000; 107 | outline:0; 108 | height:30px; 109 | width: 484px; 110 | padding-left: 1px; 111 | padding-right: 1px; 112 | } 113 | 114 | a.btn { 115 | color: #fff; 116 | text-decoration: none; 117 | user-select: none; 118 | background: #FF8000; 119 | padding: .33em 1.0em; 120 | outline: none; 121 | border-width: 1px; 122 | border-style: solid; 123 | border-color: #FDBE33 #000 #D77206; 124 | border-radius: 8px; 125 | transition: 0.2s; 126 | } 127 | a.btn:hover { background: #FFA000; } 128 | a.btn:active { background: #DAA520; } 129 | 130 | .gtr { 131 | display: block; 132 | line-height: 24px; 133 | padding: 12px 15px; 134 | cursor: pointer; 135 | } 136 | 137 | .gtr + .gtr { 138 | border-top: 1px solid #f0f2f3; 139 | } 140 | 141 | .rtg { 142 | display: none; 143 | } 144 | 145 | .mrt { 146 | position: relative; 147 | display: inline-block; 148 | vertical-align: top; 149 | margin-right: 5px; 150 | width: 18px; 151 | height: 18px; 152 | border: 2px solid #FF8000; 153 | border-radius: 12px; 154 | } 155 | 156 | .mrt:before { 157 | content: ''; 158 | display: none; 159 | position: absolute; 160 | top: 50%; 161 | left: 50%; 162 | margin: -5px 0 0 -6px; 163 | height: 4px; 164 | width: 8px; 165 | border: solid #39ca74; 166 | border-width: 0 0 4px 4px; 167 | -webkit-transform: rotate(-45deg); 168 | -moz-transform: rotate(-45deg); 169 | -ms-transform: rotate(-45deg); 170 | -o-transform: rotate(-45deg); 171 | transform: rotate(-45deg); 172 | } 173 | 174 | .rtg:checked ~ .mrt { 175 | border-color: #39ca74; 176 | } 177 | 178 | .rtg:checked ~ .mrt:before { 179 | display: block; 180 | } 181 | 182 | .lst { 183 | font-weight: bold; 184 | color: #39A9E1; 185 | } 186 | .rtg:checked ~ .lst { 187 | color: #34bf6e; 188 | } 189 | 190 | .Reslbl { 191 | position:absolute; 192 | margin-left:10px; 193 | margin-top:5px; 194 | color:#4682B4; 195 | } 196 | 197 | .ExportDIVField { 198 | background-color:#EEE8AA; 199 | padding-top:0px; 200 | padding-bottom:0px; 201 | border: 2px solid orange; 202 | border-radius:20px; 203 | display:none; 204 | } 205 | 206 | .LabelExp { 207 | float:left; 208 | padding-left:92px; 209 | 210 | } 211 | 212 | .printOwnership { 213 | font-style:italic; 214 | } 215 | 216 | @media print { 217 | .noPrint {display:none} 218 | .printThis{display:block;width:670px;margin:0px auto;text-align:center} 219 | .printThis a.btn {visibility:hidden} 220 | #PrintBtn {visibility:hidden} 221 | p.printOwnership {display:block;visibility:visible;position:static !important} 222 | } 223 | 224 | @media screen { 225 | p.printOwnership {display:none;visibility:visible;} 226 | } 227 | 228 | a.AddrLink { 229 | text-decoration:none; 230 | color:#4682B4; 231 | } 232 | 233 | a.AddrLink:active { 234 | color:#FF8C00 235 | } 236 | 237 | a.AddrLink:hover { 238 | font-size:115%; 239 | border:2px solid orange; 240 | border-radius:11px; 241 | padding:6px; 242 | } 243 | 244 | .imgPopUp span { 245 | visibility: hidden; 246 | display: none; 247 | position: fixed; 248 | bottom: 150px; 249 | left: 140px; 250 | background: #fff; 251 | box-shadow: -3px 4px 12px -2px #333; 252 | border:5px solid orange; 253 | border-radius: 5px; 254 | padding-right: 128px; 255 | padding-left: 128px; 256 | padding-top: 15px; 257 | padding-bottom: 15px; 258 | } 259 | 260 | .imgPopUp:hover span{ 261 | display:block; 262 | visibility:visible; 263 | overflow:hidden; 264 | } 265 | 266 | .imgPopUp:hover {color:#E88307;} 267 | 268 | .youtubeLink:hover {color:#E88303;} 269 | 270 | .cbx { 271 | margin: auto; 272 | margin-left: 13px; 273 | -webkit-user-select: none; 274 | user-select: none; 275 | cursor: pointer; 276 | } 277 | .cbx span { 278 | display: inline-block; 279 | vertical-align: middle; 280 | transform: translate3d(0, 0, 0); 281 | } 282 | .cbx span:first-child { 283 | position: relative; 284 | width: 18px; 285 | height: 18px; 286 | border-radius: 4px; 287 | transform: scale(1); 288 | vertical-align: middle; 289 | border: 1px solid #4682B4; 290 | transition: all 0.2s ease; 291 | } 292 | .cbx span:first-child svg { 293 | position: absolute; 294 | top: 3px; 295 | left: 2px; 296 | fill: none; 297 | stroke: #FFFFFF; 298 | stroke-width: 2; 299 | stroke-linecap: round; 300 | stroke-linejoin: round; 301 | stroke-dasharray: 16px; 302 | stroke-dashoffset: 16px; 303 | transition: all 0.3s ease; 304 | transition-delay: 0.1s; 305 | transform: translate3d(0, 0, 0); 306 | } 307 | .cbx span:first-child:before { 308 | content: ""; 309 | width: 100%; 310 | height: 100%; 311 | background: #FF8000; 312 | display: block; 313 | transform: scale(0); 314 | opacity: 1; 315 | border-radius: 50%; 316 | } 317 | .cbx span:last-child { 318 | padding-left: 8px; 319 | } 320 | .cbx:hover span:first-child { 321 | border-color: orange; 322 | } 323 | 324 | .inp-cbx:checked + .cbx span:first-child { 325 | background: orange; 326 | border-color: orange; 327 | animation: wave 0.4s ease; 328 | } 329 | .inp-cbx:checked + .cbx span:first-child svg { 330 | stroke-dashoffset: 0; 331 | } 332 | .inp-cbx:checked + .cbx span:first-child:before { 333 | transform: scale(3.5); 334 | opacity: 0; 335 | transition: all 0.6s ease; 336 | } 337 | 338 | @keyframes wave { 339 | 50% { 340 | transform: scale(0.9); 341 | } 342 | } 343 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrFreeDragon/VisualBTC/3787b85b8b68202f413ee306ccfcdb318ace3858/favicon.ico -------------------------------------------------------------------------------- /htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine On 2 | RewriteCond %{HTTPS} off 3 | RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L] 4 | 5 | RewriteCond %{HTTP_HOST} ^www\.(.*)$ 6 | RewriteRule ^(.*)$ https://%1/$1 [L,R=301] 7 | 8 | RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.html\ HTTP/ 9 | RewriteRule ^index\.html$ https://%{HTTP_HOST} [R=301,L] -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Visual BTC Generator - JS Client-Side Bitcoin Address Generator 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |

Bitcoin Visual private key generator

21 | 22 |

Youtube video tutorials:Private key generation with coinFunny pattern private key

23 |
24 | 25 | 30 | 31 | 36 | 37 |

Private Key (256bit visualization):

38 | 39 |

40 | 41 | Clear All 42 | Random Key 43 | Inverse 44 | Rotate 45 | 46 |
47 | 48 | 67 | 68 |
69 | 70 | 71 |
72 | 73 |

Generated Public Keys and Addresses:

74 | 75 |
76 |
77 |
78 |
79 | 80 | Make WIF & QR code

81 | 82 |
83 |
84 |

Your bitcoin PRIVATE KEY and ADDRESS

85 |
86 |
87 |
88 |
89 |
90 |
91 |
Private Key QR
Span text
92 |
Address QR


93 | Print my Address
94 |

Created by Visual Private Key Generator - https://btckeygen.com


95 |
96 | 97 | 98 |

99 | 100 |

(c) 2019 | Information | ZIP | GitHub | Donations: 1SoDn3auKHVwmQKRaBgkPk2hMmXzCMcPwDonation address

101 |
102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /info.txt: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # # 3 | # Visual private key generator (c) 2019 by MrFreeDragon # 4 | # # 5 | # Donations: 1SoDn3auKHVwmQKRaBgkPk2hMmXzCMcPw # 6 | # # 7 | ############################################################################### 8 | 9 | This project represents the visual bitcoin private key generator. 10 | 11 | Video tutorials: 12 | Private Key generation with a physical coin: https://www.youtube.com/watch?v=WyBdYhwweaE 13 | Genration of funny private key (for educational purposes): https://www.youtube.com/watch?v=0Ug4YBEyRFQ 14 | 15 | [1] General bitcoin information. 16 | A private key in the context of Bitcoin is a secret number that allows bitcoins to be spent. In Bitcoin, a private key is a 256-bit number, which can be represented in several ways (different formats). The "size" of this number is 32 bytes, or 256 bit (256 0/1 characters), or 64 HEX characters in the range 0-9/A-F. 17 | Any 256-bit number from 0x1 to 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141 (order of bitcoin) is a valid private key. The private key is transformed to the public address only in one way for each address type. This generator supports Legacy bitcoin addresses of both types - compressed and uncompressed. Recommendation is to use compressed key. 18 | 19 | [2] Visual presentation of the key. 20 | The square 16x16 (=256) is used for generation purposes, where each cell represents one bit. The idea is that the filled cell represents "1" bit in the key, and not filled cell represents "0" bit in the key. Such presentation allows creating visual keys which could be easily memorized by human, but hardly understood by machines. You can draw pictures, logos, figures, favorite symbols and so on. You can also make your own patterns and designs and use them as your key. The benefit from such presentation is that you can "store" this key in your memory, just remembering the way you made the drawings. 21 | 22 | [3] Coin mode. 23 | It is known that the most secure way to generate bitcoin key is to flip a coin 256 times, and write down each outcome as 1 or 0 depending on the coin side. Visual private key generator can assist you in doing it. Just start flipping the coin and filling the cells line by line from 1x1 to 16x16 and after 256 outcomes you will have a nonsense "picture" represented your unique private key. You can be sure that nobody in the world have ever generated the same key or would generate in the future. The probability of such collision is so small that it is really equal to 0 for all of us and many other future generations. See the video tutorial explaining how to generate a private key with the physical coin. 24 | 25 | [4] Random key / Inverse / Rotate - filling features of the tool 26 | (+)Random Key: Click this button for random key generation. The key is generated in random coin mode (the cells are filled randomly by 0 or 1). For more security you can change any cells to the opposite bit after random generation. 27 | (+)Inverse: Inversing all the bits to the opposite bit (changes 0 to 1, and 0 to 1). Visually the colour of every cell will be changed to the opposite one. 28 | (+)Rotate: Rotates the whole patter clockwise. All the bits are rotated clockwise. 29 | 30 | [5] Advanced options (check the tick for access). 31 | (+)Explorer: Select the transactions/balance explorer which will be used to explore your generated address (you should click on "BTC address" header near your generated address to explore the details). In most cases all your generated address will be new, without transaction history and balance. By default the explorer is BTC.com. 32 | (+)Block linkes: If you activate this option you will be ale to block the selected rows/columns of the square, and not use "these bits" in your key. The blocked line (row or column) means that all the bits in a line are preset to 0. The random option will not fill the blocked lines. You can generate the private keys with less bits in use. 33 | (+)Online check: This option uses API to connect to blockchain.info/q server and obtain the total volume of received transactions by the generated address. By activating this option you will see the total transactions volume near the address. Keep in mind, that this option requires the internet connection. THe URL of API server is stored in main JS script in var APIrequestURL. By default the Online check option is disabled. 34 | 35 | [6] Clear All. 36 | Clears all the content. 37 | 38 | [7] Own private key visualization. 39 | Tick the box near "Visualize my own HEX private key" and you will have the form to input your unique private key in HEX format. After input and clicking the "Visualize" button you will see your private key visualization in 16x16 square with corresponding bitcoin addresses and public key calculations below. The private key in HEX format consists from 64 hex symbols, so you can also use this field in order to generate your private key with the help of 16side dice (0-9,A-F) tossing it 64 times. 40 | 41 | [7] Address details in blockchain. 42 | You can easily observe the address history and address details in blockchain by clicking on the BTC address text near the generated bitcoin addresses. However particularly in all cases the generated bitcoin addresses will be new ones without any history and with zero balances. By default the BTC.com explorer is used, howver you can change it to another in advanced options (see advanced options section). 43 | 44 | [8] Make WIF & QR code. 45 | By clicking this button you will receive the addition section with all details you need to keep your private key. Click the button again to change from uncompressed to compressed format and vice versa. That section will include the private key in HEX format, the private key in WIF format, BTC address and QR codes for private key and address. Private Key WIF format is a wallet import format and understood by the most bitcoin wallets today. Print this form to store your generated private key and address with corresponding QR codes. 46 | 47 | [9] Security. 48 | The code is open source. All the private keys are generated on client side, in your browser. This site does not copy or store the information generated by you. Even so we recommend downloading this site (it is available in zip) on your computer, disconnect from the internet and generate the key offline. 49 | 50 | (c) 2019 Visual Private Key Generator by MrFreeDragon 51 | 52 | https://btckeygen.com/ 53 | -------------------------------------------------------------------------------- /js/QRcode.js: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // 3 | // QR Code Generator for JavaScript 4 | // 5 | // Copyright (c) 2009 Kazuhiko Arase 6 | // 7 | // URL: http://www.d-project.com/ 8 | // 9 | // Licensed under the MIT license: 10 | // http://www.opensource.org/licenses/mit-license.php 11 | // 12 | // The word 'QR Code' is registered trademark of 13 | // DENSO WAVE INCORPORATED 14 | // http://www.denso-wave.com/qrcode/faqpatent-e.html 15 | // 16 | //--------------------------------------------------------------------- 17 | 18 | var qrcode = function() { 19 | 20 | //--------------------------------------------------------------------- 21 | // qrcode 22 | //--------------------------------------------------------------------- 23 | 24 | /** 25 | * qrcode 26 | * @param typeNumber 1 to 40 27 | * @param errorCorrectionLevel 'L','M','Q','H' 28 | */ 29 | var qrcode = function(typeNumber, errorCorrectionLevel) { 30 | 31 | var PAD0 = 0xEC; 32 | var PAD1 = 0x11; 33 | 34 | var _typeNumber = typeNumber; 35 | var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel]; 36 | var _modules = null; 37 | var _moduleCount = 0; 38 | var _dataCache = null; 39 | var _dataList = []; 40 | 41 | var _this = {}; 42 | 43 | var makeImpl = function(test, maskPattern) { 44 | 45 | _moduleCount = _typeNumber * 4 + 17; 46 | _modules = function(moduleCount) { 47 | var modules = new Array(moduleCount); 48 | for (var row = 0; row < moduleCount; row += 1) { 49 | modules[row] = new Array(moduleCount); 50 | for (var col = 0; col < moduleCount; col += 1) { 51 | modules[row][col] = null; 52 | } 53 | } 54 | return modules; 55 | }(_moduleCount); 56 | 57 | setupPositionProbePattern(0, 0); 58 | setupPositionProbePattern(_moduleCount - 7, 0); 59 | setupPositionProbePattern(0, _moduleCount - 7); 60 | setupPositionAdjustPattern(); 61 | setupTimingPattern(); 62 | setupTypeInfo(test, maskPattern); 63 | 64 | if (_typeNumber >= 7) { 65 | setupTypeNumber(test); 66 | } 67 | 68 | if (_dataCache == null) { 69 | _dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList); 70 | } 71 | 72 | mapData(_dataCache, maskPattern); 73 | }; 74 | 75 | var setupPositionProbePattern = function(row, col) { 76 | 77 | for (var r = -1; r <= 7; r += 1) { 78 | 79 | if (row + r <= -1 || _moduleCount <= row + r) continue; 80 | 81 | for (var c = -1; c <= 7; c += 1) { 82 | 83 | if (col + c <= -1 || _moduleCount <= col + c) continue; 84 | 85 | if ( (0 <= r && r <= 6 && (c == 0 || c == 6) ) 86 | || (0 <= c && c <= 6 && (r == 0 || r == 6) ) 87 | || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { 88 | _modules[row + r][col + c] = true; 89 | } else { 90 | _modules[row + r][col + c] = false; 91 | } 92 | } 93 | } 94 | }; 95 | 96 | var getBestMaskPattern = function() { 97 | 98 | var minLostPoint = 0; 99 | var pattern = 0; 100 | 101 | for (var i = 0; i < 8; i += 1) { 102 | 103 | makeImpl(true, i); 104 | 105 | var lostPoint = QRUtil.getLostPoint(_this); 106 | 107 | if (i == 0 || minLostPoint > lostPoint) { 108 | minLostPoint = lostPoint; 109 | pattern = i; 110 | } 111 | } 112 | 113 | return pattern; 114 | }; 115 | 116 | var setupTimingPattern = function() { 117 | 118 | for (var r = 8; r < _moduleCount - 8; r += 1) { 119 | if (_modules[r][6] != null) { 120 | continue; 121 | } 122 | _modules[r][6] = (r % 2 == 0); 123 | } 124 | 125 | for (var c = 8; c < _moduleCount - 8; c += 1) { 126 | if (_modules[6][c] != null) { 127 | continue; 128 | } 129 | _modules[6][c] = (c % 2 == 0); 130 | } 131 | }; 132 | 133 | var setupPositionAdjustPattern = function() { 134 | 135 | var pos = QRUtil.getPatternPosition(_typeNumber); 136 | 137 | for (var i = 0; i < pos.length; i += 1) { 138 | 139 | for (var j = 0; j < pos.length; j += 1) { 140 | 141 | var row = pos[i]; 142 | var col = pos[j]; 143 | 144 | if (_modules[row][col] != null) { 145 | continue; 146 | } 147 | 148 | for (var r = -2; r <= 2; r += 1) { 149 | 150 | for (var c = -2; c <= 2; c += 1) { 151 | 152 | if (r == -2 || r == 2 || c == -2 || c == 2 153 | || (r == 0 && c == 0) ) { 154 | _modules[row + r][col + c] = true; 155 | } else { 156 | _modules[row + r][col + c] = false; 157 | } 158 | } 159 | } 160 | } 161 | } 162 | }; 163 | 164 | var setupTypeNumber = function(test) { 165 | 166 | var bits = QRUtil.getBCHTypeNumber(_typeNumber); 167 | 168 | for (var i = 0; i < 18; i += 1) { 169 | var mod = (!test && ( (bits >> i) & 1) == 1); 170 | _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod; 171 | } 172 | 173 | for (var i = 0; i < 18; i += 1) { 174 | var mod = (!test && ( (bits >> i) & 1) == 1); 175 | _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod; 176 | } 177 | }; 178 | 179 | var setupTypeInfo = function(test, maskPattern) { 180 | 181 | var data = (_errorCorrectionLevel << 3) | maskPattern; 182 | var bits = QRUtil.getBCHTypeInfo(data); 183 | 184 | // vertical 185 | for (var i = 0; i < 15; i += 1) { 186 | 187 | var mod = (!test && ( (bits >> i) & 1) == 1); 188 | 189 | if (i < 6) { 190 | _modules[i][8] = mod; 191 | } else if (i < 8) { 192 | _modules[i + 1][8] = mod; 193 | } else { 194 | _modules[_moduleCount - 15 + i][8] = mod; 195 | } 196 | } 197 | 198 | // horizontal 199 | for (var i = 0; i < 15; i += 1) { 200 | 201 | var mod = (!test && ( (bits >> i) & 1) == 1); 202 | 203 | if (i < 8) { 204 | _modules[8][_moduleCount - i - 1] = mod; 205 | } else if (i < 9) { 206 | _modules[8][15 - i - 1 + 1] = mod; 207 | } else { 208 | _modules[8][15 - i - 1] = mod; 209 | } 210 | } 211 | 212 | // fixed module 213 | _modules[_moduleCount - 8][8] = (!test); 214 | }; 215 | 216 | var mapData = function(data, maskPattern) { 217 | 218 | var inc = -1; 219 | var row = _moduleCount - 1; 220 | var bitIndex = 7; 221 | var byteIndex = 0; 222 | var maskFunc = QRUtil.getMaskFunction(maskPattern); 223 | 224 | for (var col = _moduleCount - 1; col > 0; col -= 2) { 225 | 226 | if (col == 6) col -= 1; 227 | 228 | while (true) { 229 | 230 | for (var c = 0; c < 2; c += 1) { 231 | 232 | if (_modules[row][col - c] == null) { 233 | 234 | var dark = false; 235 | 236 | if (byteIndex < data.length) { 237 | dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1); 238 | } 239 | 240 | var mask = maskFunc(row, col - c); 241 | 242 | if (mask) { 243 | dark = !dark; 244 | } 245 | 246 | _modules[row][col - c] = dark; 247 | bitIndex -= 1; 248 | 249 | if (bitIndex == -1) { 250 | byteIndex += 1; 251 | bitIndex = 7; 252 | } 253 | } 254 | } 255 | 256 | row += inc; 257 | 258 | if (row < 0 || _moduleCount <= row) { 259 | row -= inc; 260 | inc = -inc; 261 | break; 262 | } 263 | } 264 | } 265 | }; 266 | 267 | var createBytes = function(buffer, rsBlocks) { 268 | 269 | var offset = 0; 270 | 271 | var maxDcCount = 0; 272 | var maxEcCount = 0; 273 | 274 | var dcdata = new Array(rsBlocks.length); 275 | var ecdata = new Array(rsBlocks.length); 276 | 277 | for (var r = 0; r < rsBlocks.length; r += 1) { 278 | 279 | var dcCount = rsBlocks[r].dataCount; 280 | var ecCount = rsBlocks[r].totalCount - dcCount; 281 | 282 | maxDcCount = Math.max(maxDcCount, dcCount); 283 | maxEcCount = Math.max(maxEcCount, ecCount); 284 | 285 | dcdata[r] = new Array(dcCount); 286 | 287 | for (var i = 0; i < dcdata[r].length; i += 1) { 288 | dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset]; 289 | } 290 | offset += dcCount; 291 | 292 | var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); 293 | var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1); 294 | 295 | var modPoly = rawPoly.mod(rsPoly); 296 | ecdata[r] = new Array(rsPoly.getLength() - 1); 297 | for (var i = 0; i < ecdata[r].length; i += 1) { 298 | var modIndex = i + modPoly.getLength() - ecdata[r].length; 299 | ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0; 300 | } 301 | } 302 | 303 | var totalCodeCount = 0; 304 | for (var i = 0; i < rsBlocks.length; i += 1) { 305 | totalCodeCount += rsBlocks[i].totalCount; 306 | } 307 | 308 | var data = new Array(totalCodeCount); 309 | var index = 0; 310 | 311 | for (var i = 0; i < maxDcCount; i += 1) { 312 | for (var r = 0; r < rsBlocks.length; r += 1) { 313 | if (i < dcdata[r].length) { 314 | data[index] = dcdata[r][i]; 315 | index += 1; 316 | } 317 | } 318 | } 319 | 320 | for (var i = 0; i < maxEcCount; i += 1) { 321 | for (var r = 0; r < rsBlocks.length; r += 1) { 322 | if (i < ecdata[r].length) { 323 | data[index] = ecdata[r][i]; 324 | index += 1; 325 | } 326 | } 327 | } 328 | 329 | return data; 330 | }; 331 | 332 | var createData = function(typeNumber, errorCorrectionLevel, dataList) { 333 | 334 | var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel); 335 | 336 | var buffer = qrBitBuffer(); 337 | 338 | for (var i = 0; i < dataList.length; i += 1) { 339 | var data = dataList[i]; 340 | buffer.put(data.getMode(), 4); 341 | buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) ); 342 | data.write(buffer); 343 | } 344 | 345 | // calc num max data. 346 | var totalDataCount = 0; 347 | for (var i = 0; i < rsBlocks.length; i += 1) { 348 | totalDataCount += rsBlocks[i].dataCount; 349 | } 350 | 351 | if (buffer.getLengthInBits() > totalDataCount * 8) { 352 | throw 'code length overflow. (' 353 | + buffer.getLengthInBits() 354 | + '>' 355 | + totalDataCount * 8 356 | + ')'; 357 | } 358 | 359 | // end code 360 | if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { 361 | buffer.put(0, 4); 362 | } 363 | 364 | // padding 365 | while (buffer.getLengthInBits() % 8 != 0) { 366 | buffer.putBit(false); 367 | } 368 | 369 | // padding 370 | while (true) { 371 | 372 | if (buffer.getLengthInBits() >= totalDataCount * 8) { 373 | break; 374 | } 375 | buffer.put(PAD0, 8); 376 | 377 | if (buffer.getLengthInBits() >= totalDataCount * 8) { 378 | break; 379 | } 380 | buffer.put(PAD1, 8); 381 | } 382 | 383 | return createBytes(buffer, rsBlocks); 384 | }; 385 | 386 | _this.addData = function(data, mode) { 387 | 388 | mode = mode || 'Byte'; 389 | 390 | var newData = null; 391 | 392 | switch(mode) { 393 | case 'Numeric' : 394 | newData = qrNumber(data); 395 | break; 396 | case 'Alphanumeric' : 397 | newData = qrAlphaNum(data); 398 | break; 399 | case 'Byte' : 400 | newData = qr8BitByte(data); 401 | break; 402 | case 'Kanji' : 403 | newData = qrKanji(data); 404 | break; 405 | default : 406 | throw 'mode:' + mode; 407 | } 408 | 409 | _dataList.push(newData); 410 | _dataCache = null; 411 | }; 412 | 413 | _this.isDark = function(row, col) { 414 | if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) { 415 | throw row + ',' + col; 416 | } 417 | return _modules[row][col]; 418 | }; 419 | 420 | _this.getModuleCount = function() { 421 | return _moduleCount; 422 | }; 423 | 424 | _this.make = function() { 425 | if (_typeNumber < 1) { 426 | var typeNumber = 1; 427 | 428 | for (; typeNumber < 40; typeNumber++) { 429 | var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel); 430 | var buffer = qrBitBuffer(); 431 | 432 | for (var i = 0; i < _dataList.length; i++) { 433 | var data = _dataList[i]; 434 | buffer.put(data.getMode(), 4); 435 | buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) ); 436 | data.write(buffer); 437 | } 438 | 439 | var totalDataCount = 0; 440 | for (var i = 0; i < rsBlocks.length; i++) { 441 | totalDataCount += rsBlocks[i].dataCount; 442 | } 443 | 444 | if (buffer.getLengthInBits() <= totalDataCount * 8) { 445 | break; 446 | } 447 | } 448 | 449 | _typeNumber = typeNumber; 450 | } 451 | 452 | makeImpl(false, getBestMaskPattern() ); 453 | }; 454 | 455 | _this.createTableTag = function(cellSize, margin) { 456 | 457 | cellSize = cellSize || 2; 458 | margin = (typeof margin == 'undefined')? cellSize * 4 : margin; 459 | 460 | var qrHtml = ''; 461 | 462 | qrHtml += ''; 467 | qrHtml += ''; 468 | 469 | for (var r = 0; r < _this.getModuleCount(); r += 1) { 470 | 471 | qrHtml += ''; 472 | 473 | for (var c = 0; c < _this.getModuleCount(); c += 1) { 474 | qrHtml += ''; 487 | } 488 | 489 | qrHtml += ''; 490 | qrHtml += '
'; 484 | } 485 | 486 | qrHtml += '
'; 491 | 492 | return qrHtml; 493 | }; 494 | 495 | _this.createSvgTag = function(cellSize, margin, alt, title) { 496 | 497 | var opts = {}; 498 | if (typeof arguments[0] == 'object') { 499 | // Called by options. 500 | opts = arguments[0]; 501 | // overwrite cellSize and margin. 502 | cellSize = opts.cellSize; 503 | margin = opts.margin; 504 | alt = opts.alt; 505 | title = opts.title; 506 | } 507 | 508 | cellSize = cellSize || 2; 509 | margin = (typeof margin == 'undefined')? cellSize * 4 : margin; 510 | 511 | // Compose alt property surrogate 512 | alt = (typeof alt === 'string') ? {text: alt} : alt || {}; 513 | alt.text = alt.text || null; 514 | alt.id = (alt.text) ? alt.id || 'qrcode-description' : null; 515 | 516 | // Compose title property surrogate 517 | title = (typeof title === 'string') ? {text: title} : title || {}; 518 | title.text = title.text || null; 519 | title.id = (title.text) ? title.id || 'qrcode-title' : null; 520 | 521 | var size = _this.getModuleCount() * cellSize + margin * 2; 522 | var c, mc, r, mr, qrSvg='', rect; 523 | 524 | rect = 'l' + cellSize + ',0 0,' + cellSize + 525 | ' -' + cellSize + ',0 0,-' + cellSize + 'z '; 526 | 527 | qrSvg += '' + 535 | escapeXml(title.text) + '' : ''; 536 | qrSvg += (alt.text) ? '' + 537 | escapeXml(alt.text) + '' : ''; 538 | qrSvg += ''; 539 | qrSvg += ''; 552 | qrSvg += ''; 553 | 554 | return qrSvg; 555 | }; 556 | 557 | _this.createDataURL = function(cellSize, margin) { 558 | 559 | cellSize = cellSize || 2; 560 | margin = (typeof margin == 'undefined')? cellSize * 4 : margin; 561 | 562 | var size = _this.getModuleCount() * cellSize + margin * 2; 563 | var min = margin; 564 | var max = size - margin; 565 | 566 | return createDataURL(size, size, function(x, y) { 567 | if (min <= x && x < max && min <= y && y < max) { 568 | var c = Math.floor( (x - min) / cellSize); 569 | var r = Math.floor( (y - min) / cellSize); 570 | return _this.isDark(r, c)? 0 : 1; 571 | } else { 572 | return 1; 573 | } 574 | } ); 575 | }; 576 | 577 | _this.createImgTag = function(cellSize, margin, alt) { 578 | 579 | cellSize = cellSize || 2; 580 | margin = (typeof margin == 'undefined')? cellSize * 4 : margin; 581 | 582 | var size = _this.getModuleCount() * cellSize + margin * 2; 583 | 584 | var img = ''; 585 | img += '': escaped += '>'; break; 612 | case '&': escaped += '&'; break; 613 | case '"': escaped += '"'; break; 614 | default : escaped += c; break; 615 | } 616 | } 617 | return escaped; 618 | }; 619 | 620 | var _createHalfASCII = function(margin) { 621 | var cellSize = 1; 622 | margin = (typeof margin == 'undefined')? cellSize * 2 : margin; 623 | 624 | var size = _this.getModuleCount() * cellSize + margin * 2; 625 | var min = margin; 626 | var max = size - margin; 627 | 628 | var y, x, r1, r2, p; 629 | 630 | var blocks = { 631 | '██': '█', 632 | '█ ': '▀', 633 | ' █': '▄', 634 | ' ': ' ' 635 | }; 636 | 637 | var blocksLastLineNoMargin = { 638 | '██': '▀', 639 | '█ ': '▀', 640 | ' █': ' ', 641 | ' ': ' ' 642 | }; 643 | 644 | var ascii = ''; 645 | for (y = 0; y < size; y += 2) { 646 | r1 = Math.floor((y - min) / cellSize); 647 | r2 = Math.floor((y + 1 - min) / cellSize); 648 | for (x = 0; x < size; x += 1) { 649 | p = '█'; 650 | 651 | if (min <= x && x < max && min <= y && y < max && _this.isDark(r1, Math.floor((x - min) / cellSize))) { 652 | p = ' '; 653 | } 654 | 655 | if (min <= x && x < max && min <= y+1 && y+1 < max && _this.isDark(r2, Math.floor((x - min) / cellSize))) { 656 | p += ' '; 657 | } 658 | else { 659 | p += '█'; 660 | } 661 | 662 | // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square. 663 | ascii += (margin < 1 && y+1 >= max) ? blocksLastLineNoMargin[p] : blocks[p]; 664 | } 665 | 666 | ascii += '\n'; 667 | } 668 | 669 | if (size % 2 && margin > 0) { 670 | return ascii.substring(0, ascii.length - size - 1) + Array(size+1).join('▀'); 671 | } 672 | 673 | return ascii.substring(0, ascii.length-1); 674 | }; 675 | 676 | _this.createASCII = function(cellSize, margin) { 677 | cellSize = cellSize || 1; 678 | 679 | if (cellSize < 2) { 680 | return _createHalfASCII(margin); 681 | } 682 | 683 | cellSize -= 1; 684 | margin = (typeof margin == 'undefined')? cellSize * 2 : margin; 685 | 686 | var size = _this.getModuleCount() * cellSize + margin * 2; 687 | var min = margin; 688 | var max = size - margin; 689 | 690 | var y, x, r, p; 691 | 692 | var white = Array(cellSize+1).join('██'); 693 | var black = Array(cellSize+1).join(' '); 694 | 695 | var ascii = ''; 696 | var line = ''; 697 | for (y = 0; y < size; y += 1) { 698 | r = Math.floor( (y - min) / cellSize); 699 | line = ''; 700 | for (x = 0; x < size; x += 1) { 701 | p = 1; 702 | 703 | if (min <= x && x < max && min <= y && y < max && _this.isDark(r, Math.floor((x - min) / cellSize))) { 704 | p = 0; 705 | } 706 | 707 | // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square. 708 | line += p ? white : black; 709 | } 710 | 711 | for (r = 0; r < cellSize; r += 1) { 712 | ascii += line + '\n'; 713 | } 714 | } 715 | 716 | return ascii.substring(0, ascii.length-1); 717 | }; 718 | 719 | _this.renderTo2dContext = function(context, cellSize) { 720 | cellSize = cellSize || 2; 721 | var length = _this.getModuleCount(); 722 | for (var row = 0; row < length; row++) { 723 | for (var col = 0; col < length; col++) { 724 | context.fillStyle = _this.isDark(row, col) ? 'black' : 'white'; 725 | context.fillRect(row * cellSize, col * cellSize, cellSize, cellSize); 726 | } 727 | } 728 | } 729 | 730 | return _this; 731 | }; 732 | 733 | //--------------------------------------------------------------------- 734 | // qrcode.stringToBytes 735 | //--------------------------------------------------------------------- 736 | 737 | qrcode.stringToBytesFuncs = { 738 | 'default' : function(s) { 739 | var bytes = []; 740 | for (var i = 0; i < s.length; i += 1) { 741 | var c = s.charCodeAt(i); 742 | bytes.push(c & 0xff); 743 | } 744 | return bytes; 745 | } 746 | }; 747 | 748 | qrcode.stringToBytes = qrcode.stringToBytesFuncs['default']; 749 | 750 | //--------------------------------------------------------------------- 751 | // qrcode.createStringToBytes 752 | //--------------------------------------------------------------------- 753 | 754 | /** 755 | * @param unicodeData base64 string of byte array. 756 | * [16bit Unicode],[16bit Bytes], ... 757 | * @param numChars 758 | */ 759 | qrcode.createStringToBytes = function(unicodeData, numChars) { 760 | 761 | // create conversion map. 762 | 763 | var unicodeMap = function() { 764 | 765 | var bin = base64DecodeInputStream(unicodeData); 766 | var read = function() { 767 | var b = bin.read(); 768 | if (b == -1) throw 'eof'; 769 | return b; 770 | }; 771 | 772 | var count = 0; 773 | var unicodeMap = {}; 774 | while (true) { 775 | var b0 = bin.read(); 776 | if (b0 == -1) break; 777 | var b1 = read(); 778 | var b2 = read(); 779 | var b3 = read(); 780 | var k = String.fromCharCode( (b0 << 8) | b1); 781 | var v = (b2 << 8) | b3; 782 | unicodeMap[k] = v; 783 | count += 1; 784 | } 785 | if (count != numChars) { 786 | throw count + ' != ' + numChars; 787 | } 788 | 789 | return unicodeMap; 790 | }(); 791 | 792 | var unknownChar = '?'.charCodeAt(0); 793 | 794 | return function(s) { 795 | var bytes = []; 796 | for (var i = 0; i < s.length; i += 1) { 797 | var c = s.charCodeAt(i); 798 | if (c < 128) { 799 | bytes.push(c); 800 | } else { 801 | var b = unicodeMap[s.charAt(i)]; 802 | if (typeof b == 'number') { 803 | if ( (b & 0xff) == b) { 804 | // 1byte 805 | bytes.push(b); 806 | } else { 807 | // 2bytes 808 | bytes.push(b >>> 8); 809 | bytes.push(b & 0xff); 810 | } 811 | } else { 812 | bytes.push(unknownChar); 813 | } 814 | } 815 | } 816 | return bytes; 817 | }; 818 | }; 819 | 820 | //--------------------------------------------------------------------- 821 | // QRMode 822 | //--------------------------------------------------------------------- 823 | 824 | var QRMode = { 825 | MODE_NUMBER : 1 << 0, 826 | MODE_ALPHA_NUM : 1 << 1, 827 | MODE_8BIT_BYTE : 1 << 2, 828 | MODE_KANJI : 1 << 3 829 | }; 830 | 831 | //--------------------------------------------------------------------- 832 | // QRErrorCorrectionLevel 833 | //--------------------------------------------------------------------- 834 | 835 | var QRErrorCorrectionLevel = { 836 | L : 1, 837 | M : 0, 838 | Q : 3, 839 | H : 2 840 | }; 841 | 842 | //--------------------------------------------------------------------- 843 | // QRMaskPattern 844 | //--------------------------------------------------------------------- 845 | 846 | var QRMaskPattern = { 847 | PATTERN000 : 0, 848 | PATTERN001 : 1, 849 | PATTERN010 : 2, 850 | PATTERN011 : 3, 851 | PATTERN100 : 4, 852 | PATTERN101 : 5, 853 | PATTERN110 : 6, 854 | PATTERN111 : 7 855 | }; 856 | 857 | //--------------------------------------------------------------------- 858 | // QRUtil 859 | //--------------------------------------------------------------------- 860 | 861 | var QRUtil = function() { 862 | 863 | var PATTERN_POSITION_TABLE = [ 864 | [], 865 | [6, 18], 866 | [6, 22], 867 | [6, 26], 868 | [6, 30], 869 | [6, 34], 870 | [6, 22, 38], 871 | [6, 24, 42], 872 | [6, 26, 46], 873 | [6, 28, 50], 874 | [6, 30, 54], 875 | [6, 32, 58], 876 | [6, 34, 62], 877 | [6, 26, 46, 66], 878 | [6, 26, 48, 70], 879 | [6, 26, 50, 74], 880 | [6, 30, 54, 78], 881 | [6, 30, 56, 82], 882 | [6, 30, 58, 86], 883 | [6, 34, 62, 90], 884 | [6, 28, 50, 72, 94], 885 | [6, 26, 50, 74, 98], 886 | [6, 30, 54, 78, 102], 887 | [6, 28, 54, 80, 106], 888 | [6, 32, 58, 84, 110], 889 | [6, 30, 58, 86, 114], 890 | [6, 34, 62, 90, 118], 891 | [6, 26, 50, 74, 98, 122], 892 | [6, 30, 54, 78, 102, 126], 893 | [6, 26, 52, 78, 104, 130], 894 | [6, 30, 56, 82, 108, 134], 895 | [6, 34, 60, 86, 112, 138], 896 | [6, 30, 58, 86, 114, 142], 897 | [6, 34, 62, 90, 118, 146], 898 | [6, 30, 54, 78, 102, 126, 150], 899 | [6, 24, 50, 76, 102, 128, 154], 900 | [6, 28, 54, 80, 106, 132, 158], 901 | [6, 32, 58, 84, 110, 136, 162], 902 | [6, 26, 54, 82, 110, 138, 166], 903 | [6, 30, 58, 86, 114, 142, 170] 904 | ]; 905 | var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0); 906 | var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0); 907 | var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1); 908 | 909 | var _this = {}; 910 | 911 | var getBCHDigit = function(data) { 912 | var digit = 0; 913 | while (data != 0) { 914 | digit += 1; 915 | data >>>= 1; 916 | } 917 | return digit; 918 | }; 919 | 920 | _this.getBCHTypeInfo = function(data) { 921 | var d = data << 10; 922 | while (getBCHDigit(d) - getBCHDigit(G15) >= 0) { 923 | d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) ); 924 | } 925 | return ( (data << 10) | d) ^ G15_MASK; 926 | }; 927 | 928 | _this.getBCHTypeNumber = function(data) { 929 | var d = data << 12; 930 | while (getBCHDigit(d) - getBCHDigit(G18) >= 0) { 931 | d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) ); 932 | } 933 | return (data << 12) | d; 934 | }; 935 | 936 | _this.getPatternPosition = function(typeNumber) { 937 | return PATTERN_POSITION_TABLE[typeNumber - 1]; 938 | }; 939 | 940 | _this.getMaskFunction = function(maskPattern) { 941 | 942 | switch (maskPattern) { 943 | 944 | case QRMaskPattern.PATTERN000 : 945 | return function(i, j) { return (i + j) % 2 == 0; }; 946 | case QRMaskPattern.PATTERN001 : 947 | return function(i, j) { return i % 2 == 0; }; 948 | case QRMaskPattern.PATTERN010 : 949 | return function(i, j) { return j % 3 == 0; }; 950 | case QRMaskPattern.PATTERN011 : 951 | return function(i, j) { return (i + j) % 3 == 0; }; 952 | case QRMaskPattern.PATTERN100 : 953 | return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; }; 954 | case QRMaskPattern.PATTERN101 : 955 | return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; }; 956 | case QRMaskPattern.PATTERN110 : 957 | return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; }; 958 | case QRMaskPattern.PATTERN111 : 959 | return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; }; 960 | 961 | default : 962 | throw 'bad maskPattern:' + maskPattern; 963 | } 964 | }; 965 | 966 | _this.getErrorCorrectPolynomial = function(errorCorrectLength) { 967 | var a = qrPolynomial([1], 0); 968 | for (var i = 0; i < errorCorrectLength; i += 1) { 969 | a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) ); 970 | } 971 | return a; 972 | }; 973 | 974 | _this.getLengthInBits = function(mode, type) { 975 | 976 | if (1 <= type && type < 10) { 977 | 978 | // 1 - 9 979 | 980 | switch(mode) { 981 | case QRMode.MODE_NUMBER : return 10; 982 | case QRMode.MODE_ALPHA_NUM : return 9; 983 | case QRMode.MODE_8BIT_BYTE : return 8; 984 | case QRMode.MODE_KANJI : return 8; 985 | default : 986 | throw 'mode:' + mode; 987 | } 988 | 989 | } else if (type < 27) { 990 | 991 | // 10 - 26 992 | 993 | switch(mode) { 994 | case QRMode.MODE_NUMBER : return 12; 995 | case QRMode.MODE_ALPHA_NUM : return 11; 996 | case QRMode.MODE_8BIT_BYTE : return 16; 997 | case QRMode.MODE_KANJI : return 10; 998 | default : 999 | throw 'mode:' + mode; 1000 | } 1001 | 1002 | } else if (type < 41) { 1003 | 1004 | // 27 - 40 1005 | 1006 | switch(mode) { 1007 | case QRMode.MODE_NUMBER : return 14; 1008 | case QRMode.MODE_ALPHA_NUM : return 13; 1009 | case QRMode.MODE_8BIT_BYTE : return 16; 1010 | case QRMode.MODE_KANJI : return 12; 1011 | default : 1012 | throw 'mode:' + mode; 1013 | } 1014 | 1015 | } else { 1016 | throw 'type:' + type; 1017 | } 1018 | }; 1019 | 1020 | _this.getLostPoint = function(qrcode) { 1021 | 1022 | var moduleCount = qrcode.getModuleCount(); 1023 | 1024 | var lostPoint = 0; 1025 | 1026 | // LEVEL1 1027 | 1028 | for (var row = 0; row < moduleCount; row += 1) { 1029 | for (var col = 0; col < moduleCount; col += 1) { 1030 | 1031 | var sameCount = 0; 1032 | var dark = qrcode.isDark(row, col); 1033 | 1034 | for (var r = -1; r <= 1; r += 1) { 1035 | 1036 | if (row + r < 0 || moduleCount <= row + r) { 1037 | continue; 1038 | } 1039 | 1040 | for (var c = -1; c <= 1; c += 1) { 1041 | 1042 | if (col + c < 0 || moduleCount <= col + c) { 1043 | continue; 1044 | } 1045 | 1046 | if (r == 0 && c == 0) { 1047 | continue; 1048 | } 1049 | 1050 | if (dark == qrcode.isDark(row + r, col + c) ) { 1051 | sameCount += 1; 1052 | } 1053 | } 1054 | } 1055 | 1056 | if (sameCount > 5) { 1057 | lostPoint += (3 + sameCount - 5); 1058 | } 1059 | } 1060 | }; 1061 | 1062 | // LEVEL2 1063 | 1064 | for (var row = 0; row < moduleCount - 1; row += 1) { 1065 | for (var col = 0; col < moduleCount - 1; col += 1) { 1066 | var count = 0; 1067 | if (qrcode.isDark(row, col) ) count += 1; 1068 | if (qrcode.isDark(row + 1, col) ) count += 1; 1069 | if (qrcode.isDark(row, col + 1) ) count += 1; 1070 | if (qrcode.isDark(row + 1, col + 1) ) count += 1; 1071 | if (count == 0 || count == 4) { 1072 | lostPoint += 3; 1073 | } 1074 | } 1075 | } 1076 | 1077 | // LEVEL3 1078 | 1079 | for (var row = 0; row < moduleCount; row += 1) { 1080 | for (var col = 0; col < moduleCount - 6; col += 1) { 1081 | if (qrcode.isDark(row, col) 1082 | && !qrcode.isDark(row, col + 1) 1083 | && qrcode.isDark(row, col + 2) 1084 | && qrcode.isDark(row, col + 3) 1085 | && qrcode.isDark(row, col + 4) 1086 | && !qrcode.isDark(row, col + 5) 1087 | && qrcode.isDark(row, col + 6) ) { 1088 | lostPoint += 40; 1089 | } 1090 | } 1091 | } 1092 | 1093 | for (var col = 0; col < moduleCount; col += 1) { 1094 | for (var row = 0; row < moduleCount - 6; row += 1) { 1095 | if (qrcode.isDark(row, col) 1096 | && !qrcode.isDark(row + 1, col) 1097 | && qrcode.isDark(row + 2, col) 1098 | && qrcode.isDark(row + 3, col) 1099 | && qrcode.isDark(row + 4, col) 1100 | && !qrcode.isDark(row + 5, col) 1101 | && qrcode.isDark(row + 6, col) ) { 1102 | lostPoint += 40; 1103 | } 1104 | } 1105 | } 1106 | 1107 | // LEVEL4 1108 | 1109 | var darkCount = 0; 1110 | 1111 | for (var col = 0; col < moduleCount; col += 1) { 1112 | for (var row = 0; row < moduleCount; row += 1) { 1113 | if (qrcode.isDark(row, col) ) { 1114 | darkCount += 1; 1115 | } 1116 | } 1117 | } 1118 | 1119 | var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; 1120 | lostPoint += ratio * 10; 1121 | 1122 | return lostPoint; 1123 | }; 1124 | 1125 | return _this; 1126 | }(); 1127 | 1128 | //--------------------------------------------------------------------- 1129 | // QRMath 1130 | //--------------------------------------------------------------------- 1131 | 1132 | var QRMath = function() { 1133 | 1134 | var EXP_TABLE = new Array(256); 1135 | var LOG_TABLE = new Array(256); 1136 | 1137 | // initialize tables 1138 | for (var i = 0; i < 8; i += 1) { 1139 | EXP_TABLE[i] = 1 << i; 1140 | } 1141 | for (var i = 8; i < 256; i += 1) { 1142 | EXP_TABLE[i] = EXP_TABLE[i - 4] 1143 | ^ EXP_TABLE[i - 5] 1144 | ^ EXP_TABLE[i - 6] 1145 | ^ EXP_TABLE[i - 8]; 1146 | } 1147 | for (var i = 0; i < 255; i += 1) { 1148 | LOG_TABLE[EXP_TABLE[i] ] = i; 1149 | } 1150 | 1151 | var _this = {}; 1152 | 1153 | _this.glog = function(n) { 1154 | 1155 | if (n < 1) { 1156 | throw 'glog(' + n + ')'; 1157 | } 1158 | 1159 | return LOG_TABLE[n]; 1160 | }; 1161 | 1162 | _this.gexp = function(n) { 1163 | 1164 | while (n < 0) { 1165 | n += 255; 1166 | } 1167 | 1168 | while (n >= 256) { 1169 | n -= 255; 1170 | } 1171 | 1172 | return EXP_TABLE[n]; 1173 | }; 1174 | 1175 | return _this; 1176 | }(); 1177 | 1178 | //--------------------------------------------------------------------- 1179 | // qrPolynomial 1180 | //--------------------------------------------------------------------- 1181 | 1182 | function qrPolynomial(num, shift) { 1183 | 1184 | if (typeof num.length == 'undefined') { 1185 | throw num.length + '/' + shift; 1186 | } 1187 | 1188 | var _num = function() { 1189 | var offset = 0; 1190 | while (offset < num.length && num[offset] == 0) { 1191 | offset += 1; 1192 | } 1193 | var _num = new Array(num.length - offset + shift); 1194 | for (var i = 0; i < num.length - offset; i += 1) { 1195 | _num[i] = num[i + offset]; 1196 | } 1197 | return _num; 1198 | }(); 1199 | 1200 | var _this = {}; 1201 | 1202 | _this.getAt = function(index) { 1203 | return _num[index]; 1204 | }; 1205 | 1206 | _this.getLength = function() { 1207 | return _num.length; 1208 | }; 1209 | 1210 | _this.multiply = function(e) { 1211 | 1212 | var num = new Array(_this.getLength() + e.getLength() - 1); 1213 | 1214 | for (var i = 0; i < _this.getLength(); i += 1) { 1215 | for (var j = 0; j < e.getLength(); j += 1) { 1216 | num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) ); 1217 | } 1218 | } 1219 | 1220 | return qrPolynomial(num, 0); 1221 | }; 1222 | 1223 | _this.mod = function(e) { 1224 | 1225 | if (_this.getLength() - e.getLength() < 0) { 1226 | return _this; 1227 | } 1228 | 1229 | var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) ); 1230 | 1231 | var num = new Array(_this.getLength() ); 1232 | for (var i = 0; i < _this.getLength(); i += 1) { 1233 | num[i] = _this.getAt(i); 1234 | } 1235 | 1236 | for (var i = 0; i < e.getLength(); i += 1) { 1237 | num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio); 1238 | } 1239 | 1240 | // recursive call 1241 | return qrPolynomial(num, 0).mod(e); 1242 | }; 1243 | 1244 | return _this; 1245 | }; 1246 | 1247 | //--------------------------------------------------------------------- 1248 | // QRRSBlock 1249 | //--------------------------------------------------------------------- 1250 | 1251 | var QRRSBlock = function() { 1252 | 1253 | var RS_BLOCK_TABLE = [ 1254 | 1255 | // L 1256 | // M 1257 | // Q 1258 | // H 1259 | 1260 | // 1 1261 | [1, 26, 19], 1262 | [1, 26, 16], 1263 | [1, 26, 13], 1264 | [1, 26, 9], 1265 | 1266 | // 2 1267 | [1, 44, 34], 1268 | [1, 44, 28], 1269 | [1, 44, 22], 1270 | [1, 44, 16], 1271 | 1272 | // 3 1273 | [1, 70, 55], 1274 | [1, 70, 44], 1275 | [2, 35, 17], 1276 | [2, 35, 13], 1277 | 1278 | // 4 1279 | [1, 100, 80], 1280 | [2, 50, 32], 1281 | [2, 50, 24], 1282 | [4, 25, 9], 1283 | 1284 | // 5 1285 | [1, 134, 108], 1286 | [2, 67, 43], 1287 | [2, 33, 15, 2, 34, 16], 1288 | [2, 33, 11, 2, 34, 12], 1289 | 1290 | // 6 1291 | [2, 86, 68], 1292 | [4, 43, 27], 1293 | [4, 43, 19], 1294 | [4, 43, 15], 1295 | 1296 | // 7 1297 | [2, 98, 78], 1298 | [4, 49, 31], 1299 | [2, 32, 14, 4, 33, 15], 1300 | [4, 39, 13, 1, 40, 14], 1301 | 1302 | // 8 1303 | [2, 121, 97], 1304 | [2, 60, 38, 2, 61, 39], 1305 | [4, 40, 18, 2, 41, 19], 1306 | [4, 40, 14, 2, 41, 15], 1307 | 1308 | // 9 1309 | [2, 146, 116], 1310 | [3, 58, 36, 2, 59, 37], 1311 | [4, 36, 16, 4, 37, 17], 1312 | [4, 36, 12, 4, 37, 13], 1313 | 1314 | // 10 1315 | [2, 86, 68, 2, 87, 69], 1316 | [4, 69, 43, 1, 70, 44], 1317 | [6, 43, 19, 2, 44, 20], 1318 | [6, 43, 15, 2, 44, 16], 1319 | 1320 | // 11 1321 | [4, 101, 81], 1322 | [1, 80, 50, 4, 81, 51], 1323 | [4, 50, 22, 4, 51, 23], 1324 | [3, 36, 12, 8, 37, 13], 1325 | 1326 | // 12 1327 | [2, 116, 92, 2, 117, 93], 1328 | [6, 58, 36, 2, 59, 37], 1329 | [4, 46, 20, 6, 47, 21], 1330 | [7, 42, 14, 4, 43, 15], 1331 | 1332 | // 13 1333 | [4, 133, 107], 1334 | [8, 59, 37, 1, 60, 38], 1335 | [8, 44, 20, 4, 45, 21], 1336 | [12, 33, 11, 4, 34, 12], 1337 | 1338 | // 14 1339 | [3, 145, 115, 1, 146, 116], 1340 | [4, 64, 40, 5, 65, 41], 1341 | [11, 36, 16, 5, 37, 17], 1342 | [11, 36, 12, 5, 37, 13], 1343 | 1344 | // 15 1345 | [5, 109, 87, 1, 110, 88], 1346 | [5, 65, 41, 5, 66, 42], 1347 | [5, 54, 24, 7, 55, 25], 1348 | [11, 36, 12, 7, 37, 13], 1349 | 1350 | // 16 1351 | [5, 122, 98, 1, 123, 99], 1352 | [7, 73, 45, 3, 74, 46], 1353 | [15, 43, 19, 2, 44, 20], 1354 | [3, 45, 15, 13, 46, 16], 1355 | 1356 | // 17 1357 | [1, 135, 107, 5, 136, 108], 1358 | [10, 74, 46, 1, 75, 47], 1359 | [1, 50, 22, 15, 51, 23], 1360 | [2, 42, 14, 17, 43, 15], 1361 | 1362 | // 18 1363 | [5, 150, 120, 1, 151, 121], 1364 | [9, 69, 43, 4, 70, 44], 1365 | [17, 50, 22, 1, 51, 23], 1366 | [2, 42, 14, 19, 43, 15], 1367 | 1368 | // 19 1369 | [3, 141, 113, 4, 142, 114], 1370 | [3, 70, 44, 11, 71, 45], 1371 | [17, 47, 21, 4, 48, 22], 1372 | [9, 39, 13, 16, 40, 14], 1373 | 1374 | // 20 1375 | [3, 135, 107, 5, 136, 108], 1376 | [3, 67, 41, 13, 68, 42], 1377 | [15, 54, 24, 5, 55, 25], 1378 | [15, 43, 15, 10, 44, 16], 1379 | 1380 | // 21 1381 | [4, 144, 116, 4, 145, 117], 1382 | [17, 68, 42], 1383 | [17, 50, 22, 6, 51, 23], 1384 | [19, 46, 16, 6, 47, 17], 1385 | 1386 | // 22 1387 | [2, 139, 111, 7, 140, 112], 1388 | [17, 74, 46], 1389 | [7, 54, 24, 16, 55, 25], 1390 | [34, 37, 13], 1391 | 1392 | // 23 1393 | [4, 151, 121, 5, 152, 122], 1394 | [4, 75, 47, 14, 76, 48], 1395 | [11, 54, 24, 14, 55, 25], 1396 | [16, 45, 15, 14, 46, 16], 1397 | 1398 | // 24 1399 | [6, 147, 117, 4, 148, 118], 1400 | [6, 73, 45, 14, 74, 46], 1401 | [11, 54, 24, 16, 55, 25], 1402 | [30, 46, 16, 2, 47, 17], 1403 | 1404 | // 25 1405 | [8, 132, 106, 4, 133, 107], 1406 | [8, 75, 47, 13, 76, 48], 1407 | [7, 54, 24, 22, 55, 25], 1408 | [22, 45, 15, 13, 46, 16], 1409 | 1410 | // 26 1411 | [10, 142, 114, 2, 143, 115], 1412 | [19, 74, 46, 4, 75, 47], 1413 | [28, 50, 22, 6, 51, 23], 1414 | [33, 46, 16, 4, 47, 17], 1415 | 1416 | // 27 1417 | [8, 152, 122, 4, 153, 123], 1418 | [22, 73, 45, 3, 74, 46], 1419 | [8, 53, 23, 26, 54, 24], 1420 | [12, 45, 15, 28, 46, 16], 1421 | 1422 | // 28 1423 | [3, 147, 117, 10, 148, 118], 1424 | [3, 73, 45, 23, 74, 46], 1425 | [4, 54, 24, 31, 55, 25], 1426 | [11, 45, 15, 31, 46, 16], 1427 | 1428 | // 29 1429 | [7, 146, 116, 7, 147, 117], 1430 | [21, 73, 45, 7, 74, 46], 1431 | [1, 53, 23, 37, 54, 24], 1432 | [19, 45, 15, 26, 46, 16], 1433 | 1434 | // 30 1435 | [5, 145, 115, 10, 146, 116], 1436 | [19, 75, 47, 10, 76, 48], 1437 | [15, 54, 24, 25, 55, 25], 1438 | [23, 45, 15, 25, 46, 16], 1439 | 1440 | // 31 1441 | [13, 145, 115, 3, 146, 116], 1442 | [2, 74, 46, 29, 75, 47], 1443 | [42, 54, 24, 1, 55, 25], 1444 | [23, 45, 15, 28, 46, 16], 1445 | 1446 | // 32 1447 | [17, 145, 115], 1448 | [10, 74, 46, 23, 75, 47], 1449 | [10, 54, 24, 35, 55, 25], 1450 | [19, 45, 15, 35, 46, 16], 1451 | 1452 | // 33 1453 | [17, 145, 115, 1, 146, 116], 1454 | [14, 74, 46, 21, 75, 47], 1455 | [29, 54, 24, 19, 55, 25], 1456 | [11, 45, 15, 46, 46, 16], 1457 | 1458 | // 34 1459 | [13, 145, 115, 6, 146, 116], 1460 | [14, 74, 46, 23, 75, 47], 1461 | [44, 54, 24, 7, 55, 25], 1462 | [59, 46, 16, 1, 47, 17], 1463 | 1464 | // 35 1465 | [12, 151, 121, 7, 152, 122], 1466 | [12, 75, 47, 26, 76, 48], 1467 | [39, 54, 24, 14, 55, 25], 1468 | [22, 45, 15, 41, 46, 16], 1469 | 1470 | // 36 1471 | [6, 151, 121, 14, 152, 122], 1472 | [6, 75, 47, 34, 76, 48], 1473 | [46, 54, 24, 10, 55, 25], 1474 | [2, 45, 15, 64, 46, 16], 1475 | 1476 | // 37 1477 | [17, 152, 122, 4, 153, 123], 1478 | [29, 74, 46, 14, 75, 47], 1479 | [49, 54, 24, 10, 55, 25], 1480 | [24, 45, 15, 46, 46, 16], 1481 | 1482 | // 38 1483 | [4, 152, 122, 18, 153, 123], 1484 | [13, 74, 46, 32, 75, 47], 1485 | [48, 54, 24, 14, 55, 25], 1486 | [42, 45, 15, 32, 46, 16], 1487 | 1488 | // 39 1489 | [20, 147, 117, 4, 148, 118], 1490 | [40, 75, 47, 7, 76, 48], 1491 | [43, 54, 24, 22, 55, 25], 1492 | [10, 45, 15, 67, 46, 16], 1493 | 1494 | // 40 1495 | [19, 148, 118, 6, 149, 119], 1496 | [18, 75, 47, 31, 76, 48], 1497 | [34, 54, 24, 34, 55, 25], 1498 | [20, 45, 15, 61, 46, 16] 1499 | ]; 1500 | 1501 | var qrRSBlock = function(totalCount, dataCount) { 1502 | var _this = {}; 1503 | _this.totalCount = totalCount; 1504 | _this.dataCount = dataCount; 1505 | return _this; 1506 | }; 1507 | 1508 | var _this = {}; 1509 | 1510 | var getRsBlockTable = function(typeNumber, errorCorrectionLevel) { 1511 | 1512 | switch(errorCorrectionLevel) { 1513 | case QRErrorCorrectionLevel.L : 1514 | return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; 1515 | case QRErrorCorrectionLevel.M : 1516 | return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; 1517 | case QRErrorCorrectionLevel.Q : 1518 | return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; 1519 | case QRErrorCorrectionLevel.H : 1520 | return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; 1521 | default : 1522 | return undefined; 1523 | } 1524 | }; 1525 | 1526 | _this.getRSBlocks = function(typeNumber, errorCorrectionLevel) { 1527 | 1528 | var rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel); 1529 | 1530 | if (typeof rsBlock == 'undefined') { 1531 | throw 'bad rs block @ typeNumber:' + typeNumber + 1532 | '/errorCorrectionLevel:' + errorCorrectionLevel; 1533 | } 1534 | 1535 | var length = rsBlock.length / 3; 1536 | 1537 | var list = []; 1538 | 1539 | for (var i = 0; i < length; i += 1) { 1540 | 1541 | var count = rsBlock[i * 3 + 0]; 1542 | var totalCount = rsBlock[i * 3 + 1]; 1543 | var dataCount = rsBlock[i * 3 + 2]; 1544 | 1545 | for (var j = 0; j < count; j += 1) { 1546 | list.push(qrRSBlock(totalCount, dataCount) ); 1547 | } 1548 | } 1549 | 1550 | return list; 1551 | }; 1552 | 1553 | return _this; 1554 | }(); 1555 | 1556 | //--------------------------------------------------------------------- 1557 | // qrBitBuffer 1558 | //--------------------------------------------------------------------- 1559 | 1560 | var qrBitBuffer = function() { 1561 | 1562 | var _buffer = []; 1563 | var _length = 0; 1564 | 1565 | var _this = {}; 1566 | 1567 | _this.getBuffer = function() { 1568 | return _buffer; 1569 | }; 1570 | 1571 | _this.getAt = function(index) { 1572 | var bufIndex = Math.floor(index / 8); 1573 | return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; 1574 | }; 1575 | 1576 | _this.put = function(num, length) { 1577 | for (var i = 0; i < length; i += 1) { 1578 | _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); 1579 | } 1580 | }; 1581 | 1582 | _this.getLengthInBits = function() { 1583 | return _length; 1584 | }; 1585 | 1586 | _this.putBit = function(bit) { 1587 | 1588 | var bufIndex = Math.floor(_length / 8); 1589 | if (_buffer.length <= bufIndex) { 1590 | _buffer.push(0); 1591 | } 1592 | 1593 | if (bit) { 1594 | _buffer[bufIndex] |= (0x80 >>> (_length % 8) ); 1595 | } 1596 | 1597 | _length += 1; 1598 | }; 1599 | 1600 | return _this; 1601 | }; 1602 | 1603 | //--------------------------------------------------------------------- 1604 | // qrNumber 1605 | //--------------------------------------------------------------------- 1606 | 1607 | var qrNumber = function(data) { 1608 | 1609 | var _mode = QRMode.MODE_NUMBER; 1610 | var _data = data; 1611 | 1612 | var _this = {}; 1613 | 1614 | _this.getMode = function() { 1615 | return _mode; 1616 | }; 1617 | 1618 | _this.getLength = function(buffer) { 1619 | return _data.length; 1620 | }; 1621 | 1622 | _this.write = function(buffer) { 1623 | 1624 | var data = _data; 1625 | 1626 | var i = 0; 1627 | 1628 | while (i + 2 < data.length) { 1629 | buffer.put(strToNum(data.substring(i, i + 3) ), 10); 1630 | i += 3; 1631 | } 1632 | 1633 | if (i < data.length) { 1634 | if (data.length - i == 1) { 1635 | buffer.put(strToNum(data.substring(i, i + 1) ), 4); 1636 | } else if (data.length - i == 2) { 1637 | buffer.put(strToNum(data.substring(i, i + 2) ), 7); 1638 | } 1639 | } 1640 | }; 1641 | 1642 | var strToNum = function(s) { 1643 | var num = 0; 1644 | for (var i = 0; i < s.length; i += 1) { 1645 | num = num * 10 + chatToNum(s.charAt(i) ); 1646 | } 1647 | return num; 1648 | }; 1649 | 1650 | var chatToNum = function(c) { 1651 | if ('0' <= c && c <= '9') { 1652 | return c.charCodeAt(0) - '0'.charCodeAt(0); 1653 | } 1654 | throw 'illegal char :' + c; 1655 | }; 1656 | 1657 | return _this; 1658 | }; 1659 | 1660 | //--------------------------------------------------------------------- 1661 | // qrAlphaNum 1662 | //--------------------------------------------------------------------- 1663 | 1664 | var qrAlphaNum = function(data) { 1665 | 1666 | var _mode = QRMode.MODE_ALPHA_NUM; 1667 | var _data = data; 1668 | 1669 | var _this = {}; 1670 | 1671 | _this.getMode = function() { 1672 | return _mode; 1673 | }; 1674 | 1675 | _this.getLength = function(buffer) { 1676 | return _data.length; 1677 | }; 1678 | 1679 | _this.write = function(buffer) { 1680 | 1681 | var s = _data; 1682 | 1683 | var i = 0; 1684 | 1685 | while (i + 1 < s.length) { 1686 | buffer.put( 1687 | getCode(s.charAt(i) ) * 45 + 1688 | getCode(s.charAt(i + 1) ), 11); 1689 | i += 2; 1690 | } 1691 | 1692 | if (i < s.length) { 1693 | buffer.put(getCode(s.charAt(i) ), 6); 1694 | } 1695 | }; 1696 | 1697 | var getCode = function(c) { 1698 | 1699 | if ('0' <= c && c <= '9') { 1700 | return c.charCodeAt(0) - '0'.charCodeAt(0); 1701 | } else if ('A' <= c && c <= 'Z') { 1702 | return c.charCodeAt(0) - 'A'.charCodeAt(0) + 10; 1703 | } else { 1704 | switch (c) { 1705 | case ' ' : return 36; 1706 | case '$' : return 37; 1707 | case '%' : return 38; 1708 | case '*' : return 39; 1709 | case '+' : return 40; 1710 | case '-' : return 41; 1711 | case '.' : return 42; 1712 | case '/' : return 43; 1713 | case ':' : return 44; 1714 | default : 1715 | throw 'illegal char :' + c; 1716 | } 1717 | } 1718 | }; 1719 | 1720 | return _this; 1721 | }; 1722 | 1723 | //--------------------------------------------------------------------- 1724 | // qr8BitByte 1725 | //--------------------------------------------------------------------- 1726 | 1727 | var qr8BitByte = function(data) { 1728 | 1729 | var _mode = QRMode.MODE_8BIT_BYTE; 1730 | var _data = data; 1731 | var _bytes = qrcode.stringToBytes(data); 1732 | 1733 | var _this = {}; 1734 | 1735 | _this.getMode = function() { 1736 | return _mode; 1737 | }; 1738 | 1739 | _this.getLength = function(buffer) { 1740 | return _bytes.length; 1741 | }; 1742 | 1743 | _this.write = function(buffer) { 1744 | for (var i = 0; i < _bytes.length; i += 1) { 1745 | buffer.put(_bytes[i], 8); 1746 | } 1747 | }; 1748 | 1749 | return _this; 1750 | }; 1751 | 1752 | //--------------------------------------------------------------------- 1753 | // qrKanji 1754 | //--------------------------------------------------------------------- 1755 | 1756 | var qrKanji = function(data) { 1757 | 1758 | var _mode = QRMode.MODE_KANJI; 1759 | var _data = data; 1760 | 1761 | var stringToBytes = qrcode.stringToBytesFuncs['SJIS']; 1762 | if (!stringToBytes) { 1763 | throw 'sjis not supported.'; 1764 | } 1765 | !function(c, code) { 1766 | // self test for sjis support. 1767 | var test = stringToBytes(c); 1768 | if (test.length != 2 || ( (test[0] << 8) | test[1]) != code) { 1769 | throw 'sjis not supported.'; 1770 | } 1771 | }('\u53cb', 0x9746); 1772 | 1773 | var _bytes = stringToBytes(data); 1774 | 1775 | var _this = {}; 1776 | 1777 | _this.getMode = function() { 1778 | return _mode; 1779 | }; 1780 | 1781 | _this.getLength = function(buffer) { 1782 | return ~~(_bytes.length / 2); 1783 | }; 1784 | 1785 | _this.write = function(buffer) { 1786 | 1787 | var data = _bytes; 1788 | 1789 | var i = 0; 1790 | 1791 | while (i + 1 < data.length) { 1792 | 1793 | var c = ( (0xff & data[i]) << 8) | (0xff & data[i + 1]); 1794 | 1795 | if (0x8140 <= c && c <= 0x9FFC) { 1796 | c -= 0x8140; 1797 | } else if (0xE040 <= c && c <= 0xEBBF) { 1798 | c -= 0xC140; 1799 | } else { 1800 | throw 'illegal char at ' + (i + 1) + '/' + c; 1801 | } 1802 | 1803 | c = ( (c >>> 8) & 0xff) * 0xC0 + (c & 0xff); 1804 | 1805 | buffer.put(c, 13); 1806 | 1807 | i += 2; 1808 | } 1809 | 1810 | if (i < data.length) { 1811 | throw 'illegal char at ' + (i + 1); 1812 | } 1813 | }; 1814 | 1815 | return _this; 1816 | }; 1817 | 1818 | //===================================================================== 1819 | // GIF Support etc. 1820 | // 1821 | 1822 | //--------------------------------------------------------------------- 1823 | // byteArrayOutputStream 1824 | //--------------------------------------------------------------------- 1825 | 1826 | var byteArrayOutputStream = function() { 1827 | 1828 | var _bytes = []; 1829 | 1830 | var _this = {}; 1831 | 1832 | _this.writeByte = function(b) { 1833 | _bytes.push(b & 0xff); 1834 | }; 1835 | 1836 | _this.writeShort = function(i) { 1837 | _this.writeByte(i); 1838 | _this.writeByte(i >>> 8); 1839 | }; 1840 | 1841 | _this.writeBytes = function(b, off, len) { 1842 | off = off || 0; 1843 | len = len || b.length; 1844 | for (var i = 0; i < len; i += 1) { 1845 | _this.writeByte(b[i + off]); 1846 | } 1847 | }; 1848 | 1849 | _this.writeString = function(s) { 1850 | for (var i = 0; i < s.length; i += 1) { 1851 | _this.writeByte(s.charCodeAt(i) ); 1852 | } 1853 | }; 1854 | 1855 | _this.toByteArray = function() { 1856 | return _bytes; 1857 | }; 1858 | 1859 | _this.toString = function() { 1860 | var s = ''; 1861 | s += '['; 1862 | for (var i = 0; i < _bytes.length; i += 1) { 1863 | if (i > 0) { 1864 | s += ','; 1865 | } 1866 | s += _bytes[i]; 1867 | } 1868 | s += ']'; 1869 | return s; 1870 | }; 1871 | 1872 | return _this; 1873 | }; 1874 | 1875 | //--------------------------------------------------------------------- 1876 | // base64EncodeOutputStream 1877 | //--------------------------------------------------------------------- 1878 | 1879 | var base64EncodeOutputStream = function() { 1880 | 1881 | var _buffer = 0; 1882 | var _buflen = 0; 1883 | var _length = 0; 1884 | var _base64 = ''; 1885 | 1886 | var _this = {}; 1887 | 1888 | var writeEncoded = function(b) { 1889 | _base64 += String.fromCharCode(encode(b & 0x3f) ); 1890 | }; 1891 | 1892 | var encode = function(n) { 1893 | if (n < 0) { 1894 | // error. 1895 | } else if (n < 26) { 1896 | return 0x41 + n; 1897 | } else if (n < 52) { 1898 | return 0x61 + (n - 26); 1899 | } else if (n < 62) { 1900 | return 0x30 + (n - 52); 1901 | } else if (n == 62) { 1902 | return 0x2b; 1903 | } else if (n == 63) { 1904 | return 0x2f; 1905 | } 1906 | throw 'n:' + n; 1907 | }; 1908 | 1909 | _this.writeByte = function(n) { 1910 | 1911 | _buffer = (_buffer << 8) | (n & 0xff); 1912 | _buflen += 8; 1913 | _length += 1; 1914 | 1915 | while (_buflen >= 6) { 1916 | writeEncoded(_buffer >>> (_buflen - 6) ); 1917 | _buflen -= 6; 1918 | } 1919 | }; 1920 | 1921 | _this.flush = function() { 1922 | 1923 | if (_buflen > 0) { 1924 | writeEncoded(_buffer << (6 - _buflen) ); 1925 | _buffer = 0; 1926 | _buflen = 0; 1927 | } 1928 | 1929 | if (_length % 3 != 0) { 1930 | // padding 1931 | var padlen = 3 - _length % 3; 1932 | for (var i = 0; i < padlen; i += 1) { 1933 | _base64 += '='; 1934 | } 1935 | } 1936 | }; 1937 | 1938 | _this.toString = function() { 1939 | return _base64; 1940 | }; 1941 | 1942 | return _this; 1943 | }; 1944 | 1945 | //--------------------------------------------------------------------- 1946 | // base64DecodeInputStream 1947 | //--------------------------------------------------------------------- 1948 | 1949 | var base64DecodeInputStream = function(str) { 1950 | 1951 | var _str = str; 1952 | var _pos = 0; 1953 | var _buffer = 0; 1954 | var _buflen = 0; 1955 | 1956 | var _this = {}; 1957 | 1958 | _this.read = function() { 1959 | 1960 | while (_buflen < 8) { 1961 | 1962 | if (_pos >= _str.length) { 1963 | if (_buflen == 0) { 1964 | return -1; 1965 | } 1966 | throw 'unexpected end of file./' + _buflen; 1967 | } 1968 | 1969 | var c = _str.charAt(_pos); 1970 | _pos += 1; 1971 | 1972 | if (c == '=') { 1973 | _buflen = 0; 1974 | return -1; 1975 | } else if (c.match(/^\s$/) ) { 1976 | // ignore if whitespace. 1977 | continue; 1978 | } 1979 | 1980 | _buffer = (_buffer << 6) | decode(c.charCodeAt(0) ); 1981 | _buflen += 6; 1982 | } 1983 | 1984 | var n = (_buffer >>> (_buflen - 8) ) & 0xff; 1985 | _buflen -= 8; 1986 | return n; 1987 | }; 1988 | 1989 | var decode = function(c) { 1990 | if (0x41 <= c && c <= 0x5a) { 1991 | return c - 0x41; 1992 | } else if (0x61 <= c && c <= 0x7a) { 1993 | return c - 0x61 + 26; 1994 | } else if (0x30 <= c && c <= 0x39) { 1995 | return c - 0x30 + 52; 1996 | } else if (c == 0x2b) { 1997 | return 62; 1998 | } else if (c == 0x2f) { 1999 | return 63; 2000 | } else { 2001 | throw 'c:' + c; 2002 | } 2003 | }; 2004 | 2005 | return _this; 2006 | }; 2007 | 2008 | //--------------------------------------------------------------------- 2009 | // gifImage (B/W) 2010 | //--------------------------------------------------------------------- 2011 | 2012 | var gifImage = function(width, height) { 2013 | 2014 | var _width = width; 2015 | var _height = height; 2016 | var _data = new Array(width * height); 2017 | 2018 | var _this = {}; 2019 | 2020 | _this.setPixel = function(x, y, pixel) { 2021 | _data[y * _width + x] = pixel; 2022 | }; 2023 | 2024 | _this.write = function(out) { 2025 | 2026 | //--------------------------------- 2027 | // GIF Signature 2028 | 2029 | out.writeString('GIF87a'); 2030 | 2031 | //--------------------------------- 2032 | // Screen Descriptor 2033 | 2034 | out.writeShort(_width); 2035 | out.writeShort(_height); 2036 | 2037 | out.writeByte(0x80); // 2bit 2038 | out.writeByte(0); 2039 | out.writeByte(0); 2040 | 2041 | //--------------------------------- 2042 | // Global Color Map 2043 | 2044 | // black 2045 | out.writeByte(0x00); 2046 | out.writeByte(0x00); 2047 | out.writeByte(0x00); 2048 | 2049 | // white 2050 | out.writeByte(0xff); 2051 | out.writeByte(0xff); 2052 | out.writeByte(0xff); 2053 | 2054 | //--------------------------------- 2055 | // Image Descriptor 2056 | 2057 | out.writeString(','); 2058 | out.writeShort(0); 2059 | out.writeShort(0); 2060 | out.writeShort(_width); 2061 | out.writeShort(_height); 2062 | out.writeByte(0); 2063 | 2064 | //--------------------------------- 2065 | // Local Color Map 2066 | 2067 | //--------------------------------- 2068 | // Raster Data 2069 | 2070 | var lzwMinCodeSize = 2; 2071 | var raster = getLZWRaster(lzwMinCodeSize); 2072 | 2073 | out.writeByte(lzwMinCodeSize); 2074 | 2075 | var offset = 0; 2076 | 2077 | while (raster.length - offset > 255) { 2078 | out.writeByte(255); 2079 | out.writeBytes(raster, offset, 255); 2080 | offset += 255; 2081 | } 2082 | 2083 | out.writeByte(raster.length - offset); 2084 | out.writeBytes(raster, offset, raster.length - offset); 2085 | out.writeByte(0x00); 2086 | 2087 | //--------------------------------- 2088 | // GIF Terminator 2089 | out.writeString(';'); 2090 | }; 2091 | 2092 | var bitOutputStream = function(out) { 2093 | 2094 | var _out = out; 2095 | var _bitLength = 0; 2096 | var _bitBuffer = 0; 2097 | 2098 | var _this = {}; 2099 | 2100 | _this.write = function(data, length) { 2101 | 2102 | if ( (data >>> length) != 0) { 2103 | throw 'length over'; 2104 | } 2105 | 2106 | while (_bitLength + length >= 8) { 2107 | _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) ); 2108 | length -= (8 - _bitLength); 2109 | data >>>= (8 - _bitLength); 2110 | _bitBuffer = 0; 2111 | _bitLength = 0; 2112 | } 2113 | 2114 | _bitBuffer = (data << _bitLength) | _bitBuffer; 2115 | _bitLength = _bitLength + length; 2116 | }; 2117 | 2118 | _this.flush = function() { 2119 | if (_bitLength > 0) { 2120 | _out.writeByte(_bitBuffer); 2121 | } 2122 | }; 2123 | 2124 | return _this; 2125 | }; 2126 | 2127 | var getLZWRaster = function(lzwMinCodeSize) { 2128 | 2129 | var clearCode = 1 << lzwMinCodeSize; 2130 | var endCode = (1 << lzwMinCodeSize) + 1; 2131 | var bitLength = lzwMinCodeSize + 1; 2132 | 2133 | // Setup LZWTable 2134 | var table = lzwTable(); 2135 | 2136 | for (var i = 0; i < clearCode; i += 1) { 2137 | table.add(String.fromCharCode(i) ); 2138 | } 2139 | table.add(String.fromCharCode(clearCode) ); 2140 | table.add(String.fromCharCode(endCode) ); 2141 | 2142 | var byteOut = byteArrayOutputStream(); 2143 | var bitOut = bitOutputStream(byteOut); 2144 | 2145 | // clear code 2146 | bitOut.write(clearCode, bitLength); 2147 | 2148 | var dataIndex = 0; 2149 | 2150 | var s = String.fromCharCode(_data[dataIndex]); 2151 | dataIndex += 1; 2152 | 2153 | while (dataIndex < _data.length) { 2154 | 2155 | var c = String.fromCharCode(_data[dataIndex]); 2156 | dataIndex += 1; 2157 | 2158 | if (table.contains(s + c) ) { 2159 | 2160 | s = s + c; 2161 | 2162 | } else { 2163 | 2164 | bitOut.write(table.indexOf(s), bitLength); 2165 | 2166 | if (table.size() < 0xfff) { 2167 | 2168 | if (table.size() == (1 << bitLength) ) { 2169 | bitLength += 1; 2170 | } 2171 | 2172 | table.add(s + c); 2173 | } 2174 | 2175 | s = c; 2176 | } 2177 | } 2178 | 2179 | bitOut.write(table.indexOf(s), bitLength); 2180 | 2181 | // end code 2182 | bitOut.write(endCode, bitLength); 2183 | 2184 | bitOut.flush(); 2185 | 2186 | return byteOut.toByteArray(); 2187 | }; 2188 | 2189 | var lzwTable = function() { 2190 | 2191 | var _map = {}; 2192 | var _size = 0; 2193 | 2194 | var _this = {}; 2195 | 2196 | _this.add = function(key) { 2197 | if (_this.contains(key) ) { 2198 | throw 'dup key:' + key; 2199 | } 2200 | _map[key] = _size; 2201 | _size += 1; 2202 | }; 2203 | 2204 | _this.size = function() { 2205 | return _size; 2206 | }; 2207 | 2208 | _this.indexOf = function(key) { 2209 | return _map[key]; 2210 | }; 2211 | 2212 | _this.contains = function(key) { 2213 | return typeof _map[key] != 'undefined'; 2214 | }; 2215 | 2216 | return _this; 2217 | }; 2218 | 2219 | return _this; 2220 | }; 2221 | 2222 | var createDataURL = function(width, height, getPixel) { 2223 | var gif = gifImage(width, height); 2224 | for (var y = 0; y < height; y += 1) { 2225 | for (var x = 0; x < width; x += 1) { 2226 | gif.setPixel(x, y, getPixel(x, y) ); 2227 | } 2228 | } 2229 | 2230 | var b = byteArrayOutputStream(); 2231 | gif.write(b); 2232 | 2233 | var base64 = base64EncodeOutputStream(); 2234 | var bytes = b.toByteArray(); 2235 | for (var i = 0; i < bytes.length; i += 1) { 2236 | base64.writeByte(bytes[i]); 2237 | } 2238 | base64.flush(); 2239 | 2240 | return 'data:image/gif;base64,' + base64; 2241 | }; 2242 | 2243 | //--------------------------------------------------------------------- 2244 | // returns qrcode function. 2245 | 2246 | return qrcode; 2247 | }(); 2248 | 2249 | // multibyte support 2250 | !function() { 2251 | 2252 | qrcode.stringToBytesFuncs['UTF-8'] = function(s) { 2253 | // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array 2254 | function toUTF8Array(str) { 2255 | var utf8 = []; 2256 | for (var i=0; i < str.length; i++) { 2257 | var charcode = str.charCodeAt(i); 2258 | if (charcode < 0x80) utf8.push(charcode); 2259 | else if (charcode < 0x800) { 2260 | utf8.push(0xc0 | (charcode >> 6), 2261 | 0x80 | (charcode & 0x3f)); 2262 | } 2263 | else if (charcode < 0xd800 || charcode >= 0xe000) { 2264 | utf8.push(0xe0 | (charcode >> 12), 2265 | 0x80 | ((charcode>>6) & 0x3f), 2266 | 0x80 | (charcode & 0x3f)); 2267 | } 2268 | // surrogate pair 2269 | else { 2270 | i++; 2271 | // UTF-16 encodes 0x10000-0x10FFFF by 2272 | // subtracting 0x10000 and splitting the 2273 | // 20 bits of 0x0-0xFFFFF into two halves 2274 | charcode = 0x10000 + (((charcode & 0x3ff)<<10) 2275 | | (str.charCodeAt(i) & 0x3ff)); 2276 | utf8.push(0xf0 | (charcode >>18), 2277 | 0x80 | ((charcode>>12) & 0x3f), 2278 | 0x80 | ((charcode>>6) & 0x3f), 2279 | 0x80 | (charcode & 0x3f)); 2280 | } 2281 | } 2282 | return utf8; 2283 | } 2284 | return toUTF8Array(s); 2285 | }; 2286 | 2287 | }(); 2288 | 2289 | (function (factory) { 2290 | if (typeof define === 'function' && define.amd) { 2291 | define([], factory); 2292 | } else if (typeof exports === 'object') { 2293 | module.exports = factory(); 2294 | } 2295 | }(function () { 2296 | return qrcode; 2297 | })); -------------------------------------------------------------------------------- /js/bitcoinJS-lib.js: -------------------------------------------------------------------------------- 1 | /** 2 | * BitcoinJS-lib v0.1.3-default 3 | * Copyright (c) 2011 BitcoinJS Project 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the MIT license. 7 | */ 8 | (function(){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t=window.Crypto={},n=t.util={rotl:function(e,t){return e<>>32-t},rotr:function(e,t){return e<<32-t|e>>>t},endian:function(e){if(e.constructor==Number)return n.rotl(e,8)&16711935|n.rotl(e,24)&4278255360;for(var t=0;t0;e--)t.push(Math.floor(Math.random()*256));return t},bytesToWords:function(e){for(var t=[],n=0,r=0;n>>5]|=e[n]<<24-r%32;return t},wordsToBytes:function(e){for(var t=[],n=0;n>>5]>>>24-n%32&255);return t},bytesToHex:function(e){for(var t=[],n=0;n>>4).toString(16)),t.push((e[n]&15).toString(16));return t.join("")},hexToBytes:function(e){for(var t=[],n=0;n>>6*(3-o)&63)):n.push("=")}return n.join("")},base64ToBytes:function(t){if(typeof atob=="function")return s.stringToBytes(atob(t));t=t.replace(/[^A-Z0-9+\/]/ig,"");for(var n=[],r=0,i=0;r>>6-i*2)}return n}};t.mode={};var r=t.charenc={},i=r.UTF8={stringToBytes:function(e){return s.stringToBytes(unescape(encodeURIComponent(e)))},bytesToString:function(e){return decodeURIComponent(escape(s.bytesToString(e)))}},s=r.Binary={stringToBytes:function(e){for(var t=[],n=0;n>5]|=128<<24-i%32,n[(i+64>>9<<4)+15]=i;for(var m=0;m>>7)^(w<<14|w>>>18)^w>>>3,x=(E<<15|E>>>17)^(E<<13|E>>>19)^E>>>10;u[g]=S+(u[g-7]>>>0)+x+(u[g-16]>>>0)}var T=h&p^~h&d,N=a&f^a&l^f&l,C=(a<<30|a>>>2)^(a<<19|a>>>13)^(a<<10|a>>>22),k=(h<<26|h>>>6)^(h<<21|h>>>11)^(h<<7|h>>>25);y=(v>>>0)+k+T+s[g]+(u[g]>>>0),b=C+N,v=d,d=p,p=h,h=c+y,c=l,l=f,f=a,a=y+b}o[0]+=a,o[1]+=f,o[2]+=l,o[3]+=c,o[4]+=h,o[5]+=p,o[6]+=d,o[7]+=v}return o},o._blocksize=16})(); 10 | (function(){function o(e,t,n,r){return 0<=e&&e<=15?t^n^r:16<=e&&e<=31?t&n|~t&r:32<=e&&e<=47?(t|~n)^r:48<=e&&e<=63?t&r|n&~r:64<=e&&e<=79?t^(n|~r):"rmd160_f: j out of range"}function u(e){return 0<=e&&e<=15?0:16<=e&&e<=31?1518500249:32<=e&&e<=47?1859775393:48<=e&&e<=63?2400959708:64<=e&&e<=79?2840853838:"rmd160_K1: j out of range"}function a(e){return 0<=e&&e<=15?1352829926:16<=e&&e<=31?1548603684:32<=e&&e<=47?1836072691:48<=e&&e<=63?2053994217:64<=e&&e<=79?0:"rmd160_K2: j out of range"}function p(e,t){var n=(e&65535)+(t&65535),r=(e>>16)+(t>>16)+(n>>16);return r<<16|n&65535}function d(e,t){return e<>>32-t}var e=Crypto,t=e.util,n=e.charenc,r=n.UTF8,i=n.Binary;t.bytesToLWords=function(e){var t=Array(e.length>>2);for(var n=0;n>5]|=(e[n/8]&255)<>5]>>>n%32&255);return t};var s=e.RIPEMD160=function(e,n){var r=t.lWordsToBytes(s._rmd160(e));return n&&n.asBytes?r:n&&n.asString?i.bytesToString(r):t.bytesToHex(r)};s._rmd160=function(e){e.constructor==String&&(e=r.stringToBytes(e));var n=t.bytesToLWords(e),i=e.length*8;n[i>>5]|=128<>>9<<4)+14]=i;var s=1732584193,v=4023233417,m=2562383102,g=271733878,y=3285377520;for(var b=0;b>8&255,rng_pool[rng_pptr++]^=e>>16&255,rng_pool[rng_pptr++]^=e>>24&255,rng_pptr>=rng_psize&&(rng_pptr-=rng_psize)}function rng_seed_time(){rng_seed_int((new Date).getTime())}function rng_get_byte(){if(rng_state==null){rng_seed_time(),rng_state=prng_newstate(),rng_state.init(rng_pool);for(rng_pptr=0;rng_pptr>>8,rng_pool[rng_pptr++]=t&255;rng_pptr=0,rng_seed_time()}SecureRandom.prototype.nextBytes=rng_get_bytes; 13 | function BigInteger(e,t,n){e!=null&&("number"==typeof e?this.fromNumber(e,t,n):t==null&&"string"!=typeof e?this.fromString(e,256):this.fromString(e,t))}function nbi(){return new BigInteger(null)}function am1(e,t,n,r,i,s){while(--s>=0){var o=t*this[e++]+n[r]+i;i=Math.floor(o/67108864),n[r++]=o&67108863}return i}function am2(e,t,n,r,i,s){var o=t&32767,u=t>>15;while(--s>=0){var a=this[e]&32767,f=this[e++]>>15,l=u*a+f*o;a=o*a+((l&32767)<<15)+n[r]+(i&1073741823),i=(a>>>30)+(l>>>15)+u*f+(i>>>30),n[r++]=a&1073741823}return i}function am3(e,t,n,r,i,s){var o=t&16383,u=t>>14;while(--s>=0){var a=this[e]&16383,f=this[e++]>>14,l=u*a+f*o;a=o*a+((l&16383)<<14)+n[r]+i,i=(a>>28)+(l>>14)+u*f,n[r++]=a&268435455}return i}function int2char(e){return BI_RM.charAt(e)}function intAt(e,t){var n=BI_RC[e.charCodeAt(t)];return n==null?-1:n}function bnpCopyTo(e){for(var t=this.t-1;t>=0;--t)e[t]=this[t];e.t=this.t,e.s=this.s}function bnpFromInt(e){this.t=1,this.s=e<0?-1:0,e>0?this[0]=e:e<-1?this[0]=e+DV:this.t=0}function nbv(e){var t=nbi();return t.fromInt(e),t}function bnpFromString(e,t){var n;if(t==16)n=4;else if(t==8)n=3;else if(t==256)n=8;else if(t==2)n=1;else if(t==32)n=5;else{if(t!=4){this.fromRadix(e,t);return}n=2}this.t=0,this.s=0;var r=e.length,i=!1,s=0;while(--r>=0){var o=n==8?e[r]&255:intAt(e,r);if(o<0){e.charAt(r)=="-"&&(i=!0);continue}i=!1,s==0?this[this.t++]=o:s+n>this.DB?(this[this.t-1]|=(o&(1<>this.DB-s):this[this.t-1]|=o<=this.DB&&(s-=this.DB)}n==8&&(e[0]&128)!=0&&(this.s=-1,s>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==e)--this.t}function bnToString(e){if(this.s<0)return"-"+this.negate().toString(e);var t;if(e==16)t=4;else if(e==8)t=3;else if(e==2)t=1;else if(e==32)t=5;else{if(e!=4)return this.toRadix(e);t=2}var n=(1<0){u>u)>0&&(i=!0,s=int2char(r));while(o>=0)u>(u+=this.DB-t)):(r=this[o]>>(u-=t)&n,u<=0&&(u+=this.DB,--o)),r>0&&(i=!0),i&&(s+=int2char(r))}return i?s:"0"}function bnNegate(){var e=nbi();return BigInteger.ZERO.subTo(this,e),e}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(e){var t=this.s-e.s;if(t!=0)return t;var n=this.t;t=n-e.t;if(t!=0)return this.s<0?-t:t;while(--n>=0)if((t=this[n]-e[n])!=0)return t;return 0}function nbits(e){var t=1,n;return(n=e>>>16)!=0&&(e=n,t+=16),(n=e>>8)!=0&&(e=n,t+=8),(n=e>>4)!=0&&(e=n,t+=4),(n=e>>2)!=0&&(e=n,t+=2),(n=e>>1)!=0&&(e=n,t+=1),t}function bnBitLength(){return this.t<=0?0:this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(e,t){var n;for(n=this.t-1;n>=0;--n)t[n+e]=this[n];for(n=e-1;n>=0;--n)t[n]=0;t.t=this.t+e,t.s=this.s}function bnpDRShiftTo(e,t){for(var n=e;n=0;--u)t[u+s+1]=this[u]>>r|o,o=(this[u]&i)<=0;--u)t[u]=0;t[s]=o,t.t=this.t+s+1,t.s=this.s,t.clamp()}function bnpRShiftTo(e,t){t.s=this.s;var n=Math.floor(e/this.DB);if(n>=this.t){t.t=0;return}var r=e%this.DB,i=this.DB-r,s=(1<>r;for(var o=n+1;o>r;r>0&&(t[this.t-n-1]|=(this.s&s)<>=this.DB;if(e.t>=this.DB;r+=this.s}else{r+=this.s;while(n>=this.DB;r-=e.s}t.s=r<0?-1:0,r<-1?t[n++]=this.DV+r:r>0&&(t[n++]=r),t.t=n,t.clamp()}function bnpMultiplyTo(e,t){var n=this.abs(),r=e.abs(),i=n.t;t.t=i+r.t;while(--i>=0)t[i]=0;for(i=0;i=0)e[n]=0;for(n=0;n=t.DV&&(e[n+t.t]-=t.DV,e[n+t.t+1]=1)}e.t>0&&(e[e.t-1]+=t.am(n,t[n],e,2*n,0,1)),e.s=0,e.clamp()}function bnpDivRemTo(e,t,n){var r=e.abs();if(r.t<=0)return;var i=this.abs();if(i.t0?(r.lShiftTo(a,s),i.lShiftTo(a,n)):(r.copyTo(s),i.copyTo(n));var f=s.t,l=s[f-1];if(l==0)return;var c=l*(1<1?s[f-2]>>this.F2:0),h=this.FV/c,p=(1<=0&&(n[n.t++]=1,n.subTo(g,n)),BigInteger.ONE.dlShiftTo(f,g),g.subTo(s,s);while(s.t=0){var y=n[--v]==l?this.DM:Math.floor(n[v]*h+(n[v-1]+d)*p);if((n[v]+=s.am(0,y,n,m,0,f))0&&n.rShiftTo(a,n),o<0&&BigInteger.ZERO.subTo(n,n)}function bnMod(e){var t=nbi();return this.abs().divRemTo(e,null,t),this.s<0&&t.compareTo(BigInteger.ZERO)>0&&e.subTo(t,t),t}function Classic(e){this.m=e}function cConvert(e){return e.s<0||e.compareTo(this.m)>=0?e.mod(this.m):e}function cRevert(e){return e}function cReduce(e){e.divRemTo(this.m,null,e)}function cMulTo(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function cSqrTo(e,t){e.squareTo(t),this.reduce(t)}function bnpInvDigit(){if(this.t<1)return 0;var e=this[0];if((e&1)==0)return 0;var t=e&3;return t=t*(2-(e&15)*t)&15,t=t*(2-(e&255)*t)&255,t=t*(2-((e&65535)*t&65535))&65535,t=t*(2-e*t%this.DV)%this.DV,t>0?this.DV-t:-t}function Montgomery(e){this.m=e,this.mp=e.invDigit(),this.mpl=this.mp&32767,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(t,t),t}function montRevert(e){var t=nbi();return e.copyTo(t),this.reduce(t),t}function montReduce(e){while(e.t<=this.mt2)e[e.t++]=0;for(var t=0;t>15)*this.mpl&this.um)<<15)&e.DM;n=t+this.m.t,e[n]+=this.m.am(0,r,e,t,0,this.m.t);while(e[n]>=e.DV)e[n]-=e.DV,e[++n]++}e.clamp(),e.drShiftTo(this.m.t,e),e.compareTo(this.m)>=0&&e.subTo(this.m,e)}function montSqrTo(e,t){e.squareTo(t),this.reduce(t)}function montMulTo(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,t){if(e>4294967295||e<1)return BigInteger.ONE;var n=nbi(),r=nbi(),i=t.convert(this),s=nbits(e)-1;i.copyTo(n);while(--s>=0){t.sqrTo(n,r);if((e&1<0)t.mulTo(r,i,n);else{var o=n;n=r,r=o}}return t.revert(n)}function bnModPowInt(e,t){var n;return e<256||t.isEven()?n=new Classic(t):n=new Montgomery(t),this.exp(e,n)}var dbits,canary=0xdeadbeefcafe,j_lm=(canary&16777215)==15715070;j_lm&&navigator.appName=="Microsoft Internet Explorer"?(BigInteger.prototype.am=am2,dbits=30):j_lm&&navigator.appName!="Netscape"?(BigInteger.prototype.am=am1,dbits=26):(BigInteger.prototype.am=am3,dbits=28),BigInteger.prototype.DB=dbits,BigInteger.prototype.DM=(1<>24}function bnShortValue(){return this.t==0?this.s:this[0]<<16>>16}function bnpChunkSize(e){return Math.floor(Math.LN2*this.DB/Math.log(e))}function bnSigNum(){return this.s<0?-1:this.t<=0||this.t==1&&this[0]<=0?0:1}function bnpToRadix(e){e==null&&(e=10);if(this.signum()==0||e<2||e>36)return"0";var t=this.chunkSize(e),n=Math.pow(e,t),r=nbv(n),i=nbi(),s=nbi(),o="";this.divRemTo(r,i,s);while(i.signum()>0)o=(n+s.intValue()).toString(e).substr(1)+o,i.divRemTo(r,i,s);return s.intValue().toString(e)+o}function bnpFromRadix(e,t){this.fromInt(0),t==null&&(t=10);var n=this.chunkSize(t),r=Math.pow(t,n),i=!1,s=0,o=0;for(var u=0;u=n&&(this.dMultiply(r),this.dAddOffset(o,0),s=0,o=0)}s>0&&(this.dMultiply(Math.pow(t,s)),this.dAddOffset(o,0)),i&&BigInteger.ZERO.subTo(this,this)}function bnpFromNumber(e,t,n){if("number"==typeof t)if(e<2)this.fromInt(1);else{this.fromNumber(e,n),this.testBit(e-1)||this.bitwiseTo(BigInteger.ONE.shiftLeft(e-1),op_or,this),this.isEven()&&this.dAddOffset(1,0);while(!this.isProbablePrime(t))this.dAddOffset(2,0),this.bitLength()>e&&this.subTo(BigInteger.ONE.shiftLeft(e-1),this)}else{var r=new Array,i=e&7;r.length=(e>>3)+1,t.nextBytes(r),i>0?r[0]&=(1<0){n>n)!=(this.s&this.DM)>>n&&(t[i++]=r|this.s<=0){n<8?(r=(this[e]&(1<>(n+=this.DB-8)):(r=this[e]>>(n-=8)&255,n<=0&&(n+=this.DB,--e)),(r&128)!=0&&(r|=-256),i==0&&(this.s&128)!=(r&128)&&++i;if(i>0||r!=this.s)t[i++]=r}}return t}function bnEquals(e){return this.compareTo(e)==0}function bnMin(e){return this.compareTo(e)<0?this:e}function bnMax(e){return this.compareTo(e)>0?this:e}function bnpBitwiseTo(e,t,n){var r,i,s=Math.min(e.t,this.t);for(r=0;r>=16,t+=16),(e&255)==0&&(e>>=8,t+=8),(e&15)==0&&(e>>=4,t+=4),(e&3)==0&&(e>>=2,t+=2),(e&1)==0&&++t,t}function bnGetLowestSetBit(){for(var e=0;e=this.t?this.s!=0:(this[t]&1<>=this.DB;if(e.t>=this.DB;r+=this.s}else{r+=this.s;while(n>=this.DB;r+=e.s}t.s=r<0?-1:0,r>0?t[n++]=r:r<-1&&(t[n++]=this.DV+r),t.t=n,t.clamp()}function bnAdd(e){var t=nbi();return this.addTo(e,t),t}function bnSubtract(e){var t=nbi();return this.subTo(e,t),t}function bnMultiply(e){var t=nbi();return this.multiplyTo(e,t),t}function bnSquare(){var e=nbi();return this.squareTo(e),e}function bnDivide(e){var t=nbi();return this.divRemTo(e,t,null),t}function bnRemainder(e){var t=nbi();return this.divRemTo(e,null,t),t}function bnDivideAndRemainder(e){var t=nbi(),n=nbi();return this.divRemTo(e,t,n),new Array(t,n)}function bnpDMultiply(e){this[this.t]=this.am(0,e-1,this,0,0,this.t),++this.t,this.clamp()}function bnpDAddOffset(e,t){if(e==0)return;while(this.t<=t)this[this.t++]=0;this[t]+=e;while(this[t]>=this.DV)this[t]-=this.DV,++t>=this.t&&(this[this.t++]=0),++this[t]}function NullExp(){}function nNop(e){return e}function nMulTo(e,t,n){e.multiplyTo(t,n)}function nSqrTo(e,t){e.squareTo(t)}function bnPow(e){return this.exp(e,new NullExp)}function bnpMultiplyLowerTo(e,t,n){var r=Math.min(this.t+e.t,t);n.s=0,n.t=r;while(r>0)n[--r]=0;var i;for(i=n.t-this.t;r=0)n[r]=0;for(r=Math.max(t-this.t,0);r2*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=nbi();return e.copyTo(t),this.reduce(t),t}function barrettRevert(e){return e}function barrettReduce(e){e.drShiftTo(this.m.t-1,this.r2),e.t>this.m.t+1&&(e.t=this.m.t+1,e.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);while(e.compareTo(this.r2)<0)e.dAddOffset(1,this.m.t+1);e.subTo(this.r2,e);while(e.compareTo(this.m)>=0)e.subTo(this.m,e)}function barrettSqrTo(e,t){e.squareTo(t),this.reduce(t)}function barrettMulTo(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function bnModPow(e,t){var n=e.bitLength(),r,i=nbv(1),s;if(n<=0)return i;n<18?r=1:n<48?r=3:n<144?r=4:n<768?r=5:r=6,n<8?s=new Classic(t):t.isEven()?s=new Barrett(t):s=new Montgomery(t);var o=new Array,u=3,a=r-1,f=(1<1){var l=nbi();s.sqrTo(o[1],l);while(u<=f)o[u]=nbi(),s.mulTo(l,o[u-2],o[u]),u+=2}var c=e.t-1,h,p=!0,d=nbi(),v;n=nbits(e[c])-1;while(c>=0){n>=a?h=e[c]>>n-a&f:(h=(e[c]&(1<0&&(h|=e[c-1]>>this.DB+n-a)),u=r;while((h&1)==0)h>>=1,--u;(n-=u)<0&&(n+=this.DB,--c);if(p)o[h].copyTo(i),p=!1;else{while(u>1)s.sqrTo(i,d),s.sqrTo(d,i),u-=2;u>0?s.sqrTo(i,d):(v=i,i=d,d=v),s.mulTo(d,o[h],i)}while(c>=0&&(e[c]&1<0&&(t.rShiftTo(s,t),n.rShiftTo(s,n));while(t.signum()>0)(i=t.getLowestSetBit())>0&&t.rShiftTo(i,t),(i=n.getLowestSetBit())>0&&n.rShiftTo(i,n),t.compareTo(n)>=0?(t.subTo(n,t),t.rShiftTo(1,t)):(n.subTo(t,n),n.rShiftTo(1,n));return s>0&&n.lShiftTo(s,n),n}function bnpModInt(e){if(e<=0)return 0;var t=this.DV%e,n=this.s<0?e-1:0;if(this.t>0)if(t==0)n=this[0]%e;else for(var r=this.t-1;r>=0;--r)n=(t*n+this[r])%e;return n}function bnModInverse(e){var t=e.isEven();if(this.isEven()&&t||e.signum()==0)return BigInteger.ZERO;var n=e.clone(),r=this.clone(),i=nbv(1),s=nbv(0),o=nbv(0),u=nbv(1);while(n.signum()!=0){while(n.isEven()){n.rShiftTo(1,n);if(t){if(!i.isEven()||!s.isEven())i.addTo(this,i),s.subTo(e,s);i.rShiftTo(1,i)}else s.isEven()||s.subTo(e,s);s.rShiftTo(1,s)}while(r.isEven()){r.rShiftTo(1,r);if(t){if(!o.isEven()||!u.isEven())o.addTo(this,o),u.subTo(e,u);o.rShiftTo(1,o)}else u.isEven()||u.subTo(e,u);u.rShiftTo(1,u)}n.compareTo(r)>=0?(n.subTo(r,n),t&&i.subTo(o,i),s.subTo(u,s)):(r.subTo(n,r),t&&o.subTo(i,o),u.subTo(s,u))}return r.compareTo(BigInteger.ONE)!=0?BigInteger.ZERO:u.compareTo(e)>=0?u.subtract(e):u.signum()<0?(u.addTo(e,u),u.signum()<0?u.add(e):u):u}function bnIsProbablePrime(e){var t,n=this.abs();if(n.t==1&&n[0]<=lowprimes[lowprimes.length-1]){for(t=0;t>1,e>lowprimes.length&&(e=lowprimes.length);var i=nbi();for(var s=0;s0;--s){i=i.twice();var o=n.testBit(s),u=t.testBit(s);o!=u&&(i=i.add(o?this:r))}return i}function pointFpMultiplyTwo(e,t,n){var r;e.bitLength()>n.bitLength()?r=e.bitLength()-1:r=n.bitLength()-1;var i=this.curve.getInfinity(),s=this.add(t);while(r>=0)i=i.twice(),e.testBit(r)?n.testBit(r)?i=i.add(s):i=i.add(this):n.testBit(r)&&(i=i.add(t)),--r;return i}function ECCurveFp(e,t,n){this.q=e,this.a=this.fromBigInteger(t),this.b=this.fromBigInteger(n),this.infinity=new ECPointFp(this,null,null)}function curveFpGetQ(){return this.q}function curveFpGetA(){return this.a}function curveFpGetB(){return this.b}function curveFpEquals(e){return e==this?!0:this.q.equals(e.q)&&this.a.equals(e.a)&&this.b.equals(e.b)}function curveFpGetInfinity(){return this.infinity}function curveFpFromBigInteger(e){return new ECFieldElementFp(this.q,e)}function curveFpDecodePointHex(e){switch(parseInt(e.substr(0,2),16)){case 0:return this.infinity;case 2:case 3:return null;case 4:case 6:case 7:var t=(e.length-2)/2,n=e.substr(2,t),r=e.substr(t+2,t);return new ECPointFp(this,this.fromBigInteger(new BigInteger(n,16)),this.fromBigInteger(new BigInteger(r,16)));default:return null}}ECFieldElementFp.prototype.equals=feFpEquals,ECFieldElementFp.prototype.toBigInteger=feFpToBigInteger,ECFieldElementFp.prototype.negate=feFpNegate,ECFieldElementFp.prototype.add=feFpAdd,ECFieldElementFp.prototype.subtract=feFpSubtract,ECFieldElementFp.prototype.multiply=feFpMultiply,ECFieldElementFp.prototype.square=feFpSquare,ECFieldElementFp.prototype.divide=feFpDivide,ECPointFp.prototype.getX=pointFpGetX,ECPointFp.prototype.getY=pointFpGetY,ECPointFp.prototype.equals=pointFpEquals,ECPointFp.prototype.isInfinity=pointFpIsInfinity,ECPointFp.prototype.negate=pointFpNegate,ECPointFp.prototype.add=pointFpAdd,ECPointFp.prototype.twice=pointFpTwice,ECPointFp.prototype.multiply=pointFpMultiply,ECPointFp.prototype.multiplyTwo=pointFpMultiplyTwo,ECCurveFp.prototype.getQ=curveFpGetQ,ECCurveFp.prototype.getA=curveFpGetA,ECCurveFp.prototype.getB=curveFpGetB,ECCurveFp.prototype.equals=curveFpEquals,ECCurveFp.prototype.getInfinity=curveFpGetInfinity,ECCurveFp.prototype.fromBigInteger=curveFpFromBigInteger,ECCurveFp.prototype.decodePointHex=curveFpDecodePointHex; 16 | function X9ECParameters(e,t,n,r){this.curve=e,this.g=t,this.n=n,this.h=r}function x9getCurve(){return this.curve}function x9getG(){return this.g}function x9getN(){return this.n}function x9getH(){return this.h}function fromHex(e){return new BigInteger(e,16)}function secp128r1(){var e=fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"),t=fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"),n=fromHex("E87579C11079F43DD824993C2CEE5ED3"),r=fromHex("FFFFFFFE0000000075A30D1B9038A115"),i=BigInteger.ONE,s=new ECCurveFp(e,t,n),o=s.decodePointHex("04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83");return new X9ECParameters(s,o,r,i)}function secp160k1(){var e=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"),t=BigInteger.ZERO,n=fromHex("7"),r=fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"),i=BigInteger.ONE,s=new ECCurveFp(e,t,n),o=s.decodePointHex("043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE");return new X9ECParameters(s,o,r,i)}function secp160r1(){var e=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"),t=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"),n=fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"),r=fromHex("0100000000000000000001F4C8F927AED3CA752257"),i=BigInteger.ONE,s=new ECCurveFp(e,t,n),o=s.decodePointHex("044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32");return new X9ECParameters(s,o,r,i)}function secp192k1(){var e=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"),t=BigInteger.ZERO,n=fromHex("3"),r=fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"),i=BigInteger.ONE,s=new ECCurveFp(e,t,n),o=s.decodePointHex("04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");return new X9ECParameters(s,o,r,i)}function secp192r1(){var e=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),t=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"),n=fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"),r=fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"),i=BigInteger.ONE,s=new ECCurveFp(e,t,n),o=s.decodePointHex("04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811");return new X9ECParameters(s,o,r,i)}function secp224r1(){var e=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"),t=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"),n=fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"),r=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"),i=BigInteger.ONE,s=new ECCurveFp(e,t,n),o=s.decodePointHex("04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34");return new X9ECParameters(s,o,r,i)}function secp256k1(){var e=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"),t=BigInteger.ZERO,n=fromHex("7"),r=fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"),i=BigInteger.ONE,s=new ECCurveFp(e,t,n),o=s.decodePointHex("0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");return new X9ECParameters(s,o,r,i)}function secp256r1(){var e=fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"),t=fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"),n=fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"),r=fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"),i=BigInteger.ONE,s=new ECCurveFp(e,t,n),o=s.decodePointHex("046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");return new X9ECParameters(s,o,r,i)}function getSECCurveByName(e){return e=="secp128r1"?secp128r1():e=="secp160k1"?secp160k1():e=="secp160r1"?secp160r1():e=="secp192k1"?secp192k1():e=="secp192r1"?secp192r1():e=="secp224r1"?secp224r1():e=="secp256k1"?secp256k1():e=="secp256r1"?secp256r1():null}X9ECParameters.prototype.getCurve=x9getCurve,X9ECParameters.prototype.getG=x9getG,X9ECParameters.prototype.getN=x9getN,X9ECParameters.prototype.getH=x9getH; 17 | var EventEmitter=function(){};EventEmitter.prototype.on=function(e,t,n){n||(n=this),this._listeners||(this._listeners={}),this._listeners[e]||(this._listeners[e]=[]),this._unbinders||(this._unbinders={}),this._unbinders[e]||(this._unbinders[e]=[]);var r=function(e){t.apply(n,[e])};this._unbinders[e].push(t),this._listeners[e].push(r)},EventEmitter.prototype.trigger=function(e,t){t===undefined&&(t={}),this._listeners||(this._listeners={});if(!this._listeners[e])return;var n=this._listeners[e].length;while(n--)this._listeners[e][n](t)},EventEmitter.prototype.removeListener=function(e,t){this._unbinders||(this._unbinders={});if(!this._unbinders[e])return;var n=this._unbinders[e].length;while(n--)this._unbinders[e][n]===t&&(this._unbinders[e].splice(n,1),this._listeners[e].splice(n,1))},EventEmitter.augment=function(e){for(var t in EventEmitter.prototype)e[t]||(e[t]=EventEmitter.prototype[t])}; 18 | (function(e){var t=e;"object"!=typeof module&&(t.EventEmitter=EventEmitter)})("object"==typeof module?module.exports:window.Bitcoin={}); 19 | BigInteger.valueOf=nbv,BigInteger.prototype.toByteArrayUnsigned=function(){var e=this.abs().toByteArray();return e.length?(e[0]==0&&(e=e.slice(1)),e.map(function(e){return e<0?e+256:e})):e},BigInteger.fromByteArrayUnsigned=function(e){return e.length?e[0]&128?new BigInteger([0].concat(e)):new BigInteger(e):e.valueOf(0)},BigInteger.prototype.toByteArraySigned=function(){var e=this.abs().toByteArrayUnsigned(),t=this.compareTo(BigInteger.ZERO)<0;return t?e[0]&128?e.unshift(128):e[0]|=128:e[0]&128&&e.unshift(0),e},BigInteger.fromByteArraySigned=function(e){return e[0]&128?(e[0]&=127,BigInteger.fromByteArrayUnsigned(e).negate()):BigInteger.fromByteArrayUnsigned(e)};var names=["log","debug","info","warn","error","assert","dir","dirxml","group","groupEnd","time","timeEnd","count","trace","profile","profileEnd"];"undefined"==typeof window.console&&(window.console={});for(var i=0;i>>8,e&255]:e<=1?[254].concat(Crypto.util.wordsToBytes([e])):[255].concat(Crypto.util.wordsToBytes([e>>>32,e]))},valueToBigInt:function(e){return e instanceof BigInteger?e:BigInteger.fromByteArrayUnsigned(e)},formatValue:function(e){var t=this.valueToBigInt(e).toString(),n=t.length>8?t.substr(0,t.length-8):"0",r=t.length>8?t.substr(t.length-8):t;while(r.length<8)r="0"+r;r=r.replace(/0*$/,"");while(r.length<2)r+="0";return n+"."+r},parseValue:function(e){var t=e.split("."),n=t[0],r=t[1]||"0";while(r.length<8)r+="0";r=r.replace(/^0+/g,"");var i=BigInteger.valueOf(parseInt(n));return i=i.multiply(BigInteger.valueOf(1e8)),i=i.add(BigInteger.valueOf(parseInt(r))),i},sha256ripe160:function(e){return Crypto.RIPEMD160(Crypto.SHA256(e,{asBytes:!0}),{asBytes:!0})}};for(var i in Crypto.util)Crypto.util.hasOwnProperty(i)&&(Bitcoin.Util[i]=Crypto.util[i]); 20 | (function(e){e.Base58={alphabet:"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",validRegex:/^[1-9A-HJ-NP-Za-km-z]+$/,base:BigInteger.valueOf(58),encode:function(e){var n=BigInteger.fromByteArrayUnsigned(e),r=[];while(n.compareTo(t.base)>=0){var i=n.mod(t.base);r.unshift(t.alphabet[i.intValue()]),n=n.subtract(i).divide(t.base)}r.unshift(t.alphabet[n.intValue()]);for(var s=0;s=0;i--){var s=t.alphabet.indexOf(e[i]);if(s<0)throw"Invalid character";n=n.add(BigInteger.valueOf(s).multiply(t.base.pow(e.length-1-i))),e[i]=="1"?r++:r=0}var o=n.toByteArrayUnsigned();while(r-->0)o.unshift(0);return o}};var t=e.Base58})("undefined"!=typeof Bitcoin?Bitcoin:module.exports); 21 | Bitcoin.Address=function(e){"string"==typeof e&&(e=Bitcoin.Address.decodeString(e)),this.hash=e,this.version=0},Bitcoin.Address.prototype.toString=function(){var e=this.hash.slice(0);e.unshift(this.version);var t=Crypto.SHA256(Crypto.SHA256(e,{asBytes:!0}),{asBytes:!0}),n=e.concat(t.slice(0,4));return Bitcoin.Base58.encode(n)},Bitcoin.Address.prototype.getHashBase64=function(){return Crypto.util.bytesToBase64(this.hash)},Bitcoin.Address.decodeString=function(e){var t=Bitcoin.Base58.decode(e),n=t.slice(0,21),r=Crypto.SHA256(Crypto.SHA256(n,{asBytes:!0}),{asBytes:!0});if(r[0]!=t[21]||r[1]!=t[22]||r[2]!=t[23]||r[3]!=t[24])throw"Checksum validation failed!";var i=n.shift();if(i!=0)throw"Version "+i+" not supported!";return n}; 22 | function integerToBytes(e,t){var n=e.toByteArrayUnsigned();if(tn.length)n.unshift(0);return n}function dmp(e){return e instanceof BigInteger||(e=e.toBigInteger()),Crypto.util.bytesToHex(e.toByteArrayUnsigned())}ECFieldElementFp.prototype.getByteLength=function(){return Math.floor((this.toBigInteger().bitLength()+7)/8)},ECPointFp.prototype.getEncoded=function(e){var t=this.getX().toBigInteger(),n=this.getY().toBigInteger(),r=integerToBytes(t,32);return e?n.isEven()?r.unshift(2):r.unshift(3):(r.unshift(4),r=r.concat(integerToBytes(n,32))),r},ECPointFp.decodeFrom=function(e,t){var n=t[0],r=t.length-1,i=t.slice(1,1+r/2),s=t.slice(1+r/2,1+r);i.unshift(0),s.unshift(0);var o=new BigInteger(i),u=new BigInteger(s);return new ECPointFp(e,e.fromBigInteger(o),e.fromBigInteger(u))},ECPointFp.prototype.add2D=function(e){if(this.isInfinity())return e;if(e.isInfinity())return this;if(this.x.equals(e.x))return this.y.equals(e.y)?this.twice():this.curve.getInfinity();var t=e.x.subtract(this.x),n=e.y.subtract(this.y),r=n.divide(t),i=r.square().subtract(this.x).subtract(e.x),s=r.multiply(this.x.subtract(i)).subtract(this.y);return new ECPointFp(this.curve,i,s)},ECPointFp.prototype.twice2D=function(){if(this.isInfinity())return this;if(this.y.toBigInteger().signum()==0)return this.curve.getInfinity();var e=this.curve.fromBigInteger(BigInteger.valueOf(2)),t=this.curve.fromBigInteger(BigInteger.valueOf(3)),n=this.x.square().multiply(t).add(this.curve.a).divide(this.y.multiply(e)),r=n.square().subtract(this.x.multiply(e)),i=n.multiply(this.x.subtract(r)).subtract(this.y);return new ECPointFp(this.curve,r,i)},ECPointFp.prototype.multiply2D=function(e){if(this.isInfinity())return this;if(e.signum()==0)return this.curve.getInfinity();var t=e,n=t.multiply(new BigInteger("3")),r=this.negate(),i=this,s;for(s=n.bitLength()-2;s>0;--s){i=i.twice();var o=n.testBit(s),u=t.testBit(s);o!=u&&(i=i.add2D(o?this:r))}return i},ECPointFp.prototype.isOnCurve=function(){var e=this.getX().toBigInteger(),t=this.getY().toBigInteger(),n=this.curve.getA().toBigInteger(),r=this.curve.getB().toBigInteger(),i=this.curve.getQ(),s=t.multiply(t).mod(i),o=e.multiply(e).multiply(e).add(n.multiply(e)).add(r).mod(i);return s.equals(o)},ECPointFp.prototype.toString=function(){return"("+this.getX().toBigInteger().toString()+","+this.getY().toBigInteger().toString()+")"},ECPointFp.prototype.validate=function(){var e=this.curve.getQ();if(this.isInfinity())throw new Error("Point is at infinity.");var t=this.getX().toBigInteger(),n=this.getY().toBigInteger();if(t.compareTo(BigInteger.ONE)<0||t.compareTo(e.subtract(BigInteger.ONE))>0)throw new Error("x coordinate out of bounds");if(n.compareTo(BigInteger.ONE)<0||n.compareTo(e.subtract(BigInteger.ONE))>0)throw new Error("y coordinate out of bounds");if(!this.isOnCurve())throw new Error("Point is not on the curve.");if(this.multiply(e).isInfinity())throw new Error("Point is not a scalar multiple of G.");return!0},Bitcoin.ECDSA=function(){function r(e,t,n,r){var i=Math.max(t.bitLength(),r.bitLength()),s=e.add2D(n),o=e.curve.getInfinity();for(var u=i-1;u>=0;--u)o=o.twice2D(),o.z=BigInteger.ONE,t.testBit(u)?r.testBit(u)?o=o.add2D(s):o=o.add2D(e):r.testBit(u)&&(o=o.add2D(n));return o}var e=getSECCurveByName("secp256k1"),t=new SecureRandom,n=null,i={getBigRandom:function(e){return(new BigInteger(e.bitLength(),t)).mod(e.subtract(BigInteger.ONE)).add(BigInteger.ONE)},sign:function(t,n){var r=n,s=e.getN(),o=BigInteger.fromByteArrayUnsigned(t);do var u=i.getBigRandom(s),a=e.getG(),f=a.multiply(u),l=f.getX().toBigInteger().mod(s);while(l.compareTo(BigInteger.ZERO)<=0);var c=u.modInverse(s).multiply(o.add(r.multiply(l))).mod(s);return i.serializeSig(l,c)},verify:function(t,n,r){var s,o;if(Bitcoin.Util.isArray(n)){var u=i.parseSig(n);s=u.r,o=u.s}else{if("object"!=typeof n||!n.r||!n.s)throw"Invalid value for signature";s=n.r,o=n.s}var a;if(r instanceof ECPointFp)a=r;else{if(!Bitcoin.Util.isArray(r))throw"Invalid format for pubkey value, must be byte array or ECPointFp";a=ECPointFp.decodeFrom(e.getCurve(),r)}var f=BigInteger.fromByteArrayUnsigned(t);return i.verifyRaw(f,s,o,a)},verifyRaw:function(t,n,r,i){var s=e.getN(),o=e.getG();if(n.compareTo(BigInteger.ONE)<0||n.compareTo(s)>=0)return!1;if(r.compareTo(BigInteger.ONE)<0||r.compareTo(s)>=0)return!1;var u=r.modInverse(s),a=t.multiply(u).mod(s),f=n.multiply(u).mod(s),l=o.multiply(a).add(i.multiply(f)),c=l.getX().toBigInteger().mod(s);return c.equals(n)},serializeSig:function(e,t){var n=e.toByteArraySigned(),r=t.toByteArraySigned(),i=[];return i.push(2),i.push(n.length),i=i.concat(n),i.push(2),i.push(r.length),i=i.concat(r),i.unshift(i.length),i.unshift(48),i},parseSig:function(e){var t;if(e[0]!=48)throw new Error("Signature not a valid DERSequence");t=2;if(e[t]!=2)throw new Error("First element in signature must be a DERInteger");var n=e.slice(t+2,t+2+e[t+1]);t+=2+e[t+1];if(e[t]!=2)throw new Error("Second element in signature must be a DERInteger");var r=e.slice(t+2,t+2+e[t+1]);t+=2+e[t+1];var i=BigInteger.fromByteArrayUnsigned(n),s=BigInteger.fromByteArrayUnsigned(r);return{r:i,s:s}},parseSigCompact:function(t){if(t.length!==65)throw"Signature has the wrong length";var n=t[0]-27;if(n<0||n>7)throw"Invalid signature type";var r=e.getN(),i=BigInteger.fromByteArrayUnsigned(t.slice(1,33)).mod(r),s=BigInteger.fromByteArrayUnsigned(t.slice(33,65)).mod(r);return{r:i,s:s,i:n}},recoverPubKey:function(t,s,o,u){u&=3;var a=u&1,f=u>>1,l=e.getN(),c=e.getG(),h=e.getCurve(),p=h.getQ(),d=h.getA().toBigInteger(),v=h.getB().toBigInteger();n||(n=p.add(BigInteger.ONE).divide(BigInteger.valueOf(4)));var m=f?t.add(l):t,g=m.multiply(m).multiply(m).add(d.multiply(m)).add(v).mod(p),y=g.modPow(n,p),b=y.isEven()?u%2:(u+1)%2,w=(y.isEven()?!a:a)?y:p.subtract(y),E=new ECPointFp(h,h.fromBigInteger(m),h.fromBigInteger(w));E.validate();var S=BigInteger.fromByteArrayUnsigned(o),x=BigInteger.ZERO.subtract(S).mod(l),T=t.modInverse(l),N=r(E,s,c,x).multiply(T);console.log("G.x: ",Crypto.util.bytesToHex(c.x.toBigInteger().toByteArrayUnsigned())),console.log("G.y: ",Crypto.util.bytesToHex(c.y.toBigInteger().toByteArrayUnsigned())),console.log("s: ",Crypto.util.bytesToHex(T.toByteArrayUnsigned())),console.log("Q.x: ",Crypto.util.bytesToHex(N.x.toBigInteger().toByteArrayUnsigned())),console.log("Q.y: ",Crypto.util.bytesToHex(N.y.toBigInteger().toByteArrayUnsigned())),N.validate();if(!i.verifyRaw(S,t,s,N))throw"Pubkey recovery unsuccessful";var C=new Bitcoin.ECKey;return C.pub=N,C},calcPubkeyRecoveryParam:function(e,t,n,r){for(var i=0;i<4;i++)try{var s=Bitcoin.ECDSA.recoverPubKey(t,n,r,i);if(s.getBitcoinAddress().toString()==e)return i}catch(o){}throw"Unable to find valid recovery factor"}};return i}(); 23 | Bitcoin.ECKey=function(){var e=Bitcoin.ECDSA,t=getSECCurveByName("secp256k1"),n=new SecureRandom,r=function(n){if(!n){var i=t.getN();this.priv=e.getBigRandom(i)}else n instanceof BigInteger?this.priv=n:Bitcoin.Util.isArray(n)?this.priv=BigInteger.fromByteArrayUnsigned(n):"string"==typeof n&&(n.length==51&&n[0]=="5"?this.priv=BigInteger.fromByteArrayUnsigned(r.decodeString(n)):this.priv=BigInteger.fromByteArrayUnsigned(Crypto.util.base64ToBytes(n)));this.compressed=!!r.compressByDefault};return r.compressByDefault=!1,r.prototype.setCompressed=function(e){this.compressed=!!e},r.prototype.getPub=function(){return this.getPubPoint().getEncoded(this.compressed)},r.prototype.getPubPoint=function(){return this.pub||(this.pub=t.getG().multiply(this.priv)),this.pub},r.prototype.getPubKeyHash=function(){return this.pubKeyHash?this.pubKeyHash:this.pubKeyHash=Bitcoin.Util.sha256ripe160(this.getPub())},r.prototype.getBitcoinAddress=function(){var e=this.getPubKeyHash(),t=new Bitcoin.Address(e);return t},r.prototype.getExportedPrivateKey=function(){var e=this.priv.toByteArrayUnsigned();while(e.length<32)e.unshift(0);e.unshift(128);var t=Crypto.SHA256(Crypto.SHA256(e,{asBytes:!0}),{asBytes:!0}),n=e.concat(t.slice(0,4));return Bitcoin.Base58.encode(n)},r.prototype.setPub=function(e){this.pub=ECPointFp.decodeFrom(t.getCurve(),e)},r.prototype.toString=function(e){return e==="base64"?Crypto.util.bytesToBase64(this.priv.toByteArrayUnsigned()):Crypto.util.bytesToHex(this.priv.toByteArrayUnsigned())},r.prototype.sign=function(t){return e.sign(t,this.priv)},r.prototype.verify=function(t,n){return e.verify(t,n,this.getPub())},r.decodeString=function(e){var t=Bitcoin.Base58.decode(e),n=t.slice(0,33),r=Crypto.SHA256(Crypto.SHA256(n,{asBytes:!0}),{asBytes:!0});if(r[0]!=t[33]||r[1]!=t[34]||r[2]!=t[35]||r[3]!=t[36])throw"Checksum validation failed!";var i=n.shift();if(i!=128)throw"Version "+i+" not supported!";return n},r}(); 24 | (function(){var e=Bitcoin.Opcode=function(e){this.code=e};e.prototype.toString=function(){return e.reverseMap[this.code]},e.map={OP_0:0,OP_FALSE:0,OP_PUSHDATA1:76,OP_PUSHDATA2:77,OP_PUSHDATA4:78,OP_1NEGATE:79,OP_RESERVED:80,OP_1:81,OP_TRUE:81,OP_2:82,OP_3:83,OP_4:84,OP_5:85,OP_6:86,OP_7:87,OP_8:88,OP_9:89,OP_10:90,OP_11:91,OP_12:92,OP_13:93,OP_14:94,OP_15:95,OP_16:96,OP_NOP:97,OP_VER:98,OP_IF:99,OP_NOTIF:100,OP_VERIF:101,OP_VERNOTIF:102,OP_ELSE:103,OP_ENDIF:104,OP_VERIFY:105,OP_RETURN:106,OP_TOALTSTACK:107,OP_FROMALTSTACK:108,OP_2DROP:109,OP_2DUP:110,OP_3DUP:111,OP_2OVER:112,OP_2ROT:113,OP_2SWAP:114,OP_IFDUP:115,OP_DEPTH:116,OP_DROP:117,OP_DUP:118,OP_NIP:119,OP_OVER:120,OP_PICK:121,OP_ROLL:122,OP_ROT:123,OP_SWAP:124,OP_TUCK:125,OP_CAT:126,OP_SUBSTR:127,OP_LEFT:128,OP_RIGHT:129,OP_SIZE:130,OP_INVERT:131,OP_AND:132,OP_OR:133,OP_XOR:134,OP_EQUAL:135,OP_EQUALVERIFY:136,OP_RESERVED1:137,OP_RESERVED2:138,OP_1ADD:139,OP_1SUB:140,OP_2MUL:141,OP_2DIV:142,OP_NEGATE:143,OP_ABS:144,OP_NOT:145,OP_0NOTEQUAL:146,OP_ADD:147,OP_SUB:148,OP_MUL:149,OP_DIV:150,OP_MOD:151,OP_LSHIFT:152,OP_RSHIFT:153,OP_BOOLAND:154,OP_BOOLOR:155,OP_NUMEQUAL:156,OP_NUMEQUALVERIFY:157,OP_NUMNOTEQUAL:158,OP_LESSTHAN:159,OP_GREATERTHAN:160,OP_LESSTHANOREQUAL:161,OP_GREATERTHANOREQUAL:162,OP_MIN:163,OP_MAX:164,OP_WITHIN:165,OP_RIPEMD160:166,OP_SHA1:167,OP_SHA256:168,OP_HASH160:169,OP_HASH256:170,OP_CODESEPARATOR:171,OP_CHECKSIG:172,OP_CHECKSIGVERIFY:173,OP_CHECKMULTISIG:174,OP_CHECKMULTISIGVERIFY:175,OP_NOP1:176,OP_NOP2:177,OP_NOP3:178,OP_NOP4:179,OP_NOP5:180,OP_NOP6:181,OP_NOP7:182,OP_NOP8:183,OP_NOP9:184,OP_NOP10:185,OP_PUBKEYHASH:253,OP_PUBKEY:254,OP_INVALIDOPCODE:255},e.reverseMap=[];for(var t in e.map)e.reverseMap[e.map[t]]=t})(); 25 | (function(){var Opcode=Bitcoin.Opcode;for(var i in Opcode.map)eval("var "+i+" = "+Opcode.map[i]+";");var Script=Bitcoin.Script=function(e){if(!e)this.buffer=[];else if("string"==typeof e)this.buffer=Crypto.util.base64ToBytes(e);else if(Bitcoin.Util.isArray(e))this.buffer=e;else{if(!(e instanceof Script))throw new Error("Invalid script");this.buffer=e.buffer}this.parse()};Script.prototype.parse=function(){function n(n){e.chunks.push(e.buffer.slice(t,t+n)),t+=n}var e=this;this.chunks=[];var t=0;while(t=240&&(r=r<<8|this.buffer[t++]);var i;r>0&&r>>8&255)):(this.buffer.push(OP_PUSHDATA4),this.buffer.push(e.length&255),this.buffer.push(e.length>>>8&255),this.buffer.push(e.length>>>16&255),this.buffer.push(e.length>>>24&255)),this.buffer=this.buffer.concat(e),this.chunks.push(e)},Script.createOutputScript=function(e){var t=new Script;return t.writeOp(OP_DUP),t.writeOp(OP_HASH160),t.writeBytes(e.hash),t.writeOp(OP_EQUALVERIFY),t.writeOp(OP_CHECKSIG),t},Script.prototype.extractAddresses=function(e){switch(this.getOutType()){case"Address":return e.push(new Address(this.chunks[2])),1;case"Pubkey":return e.push(new Address(Util.sha256ripe160(this.chunks[0]))),1;case"Multisig":for(var t=1;t=0;o--){var u=this.outs[o],a=u.script.simpleOutPubKeyHash();e.hasHash(a)?i=a:n=!1,r=a}for(var o=this.ins.length-1;o>=0;o--){var f=this.ins[o];s=f.script.simpleInPubKeyHash();if(!e.hasHash(s)){t=!1;break}}var l=this.calcImpact(e),c={};return c.impact=l,l.sign>0&&l.value.compareTo(BigInteger.ZERO)>0?(c.type="recv",c.addr=new Bitcoin.Address(i)):t&&n?c.type="self":t?(c.type="sent",c.addr=new Bitcoin.Address(r)):c.type="other",c}return null},t.prototype.getDescription=function(e){var t=this.analyze(e);if(!t)return"";switch(t.type){case"recv":return"Received with "+t.addr;case"sent":return"Payment to "+t.addr;case"self":return"Payment to yourself";case"other":default:return""}},t.prototype.getTotalOutValue=function(){var e=BigInteger.ZERO;for(var t=0;t=0?{sign:1,value:t.subtract(s)}:{sign:-1,value:s.subtract(t)}}return BigInteger.ZERO};var u=Bitcoin.TransactionIn=function(t){this.outpoint=t.outpoint,t.script instanceof e?this.script=t.script:this.script=new e(t.script),this.sequence=t.sequence};u.prototype.clone=function(){var e=new u({outpoint:{hash:this.outpoint.hash,index:this.outpoint.index},script:this.script.clone(),sequence:this.sequence});return e};var a=Bitcoin.TransactionOut=function(t){t.script instanceof e?this.script=t.script:this.script=new e(t.script);if(Bitcoin.Util.isArray(t.value))this.value=t.value;else if("string"==typeof t.value){var n=(new BigInteger(t.value,10)).toString(16);while(n.length<16)n="0"+n;this.value=Crypto.util.hexToBytes(n)}};a.prototype.clone=function(){var e=new a({script:this.script.clone(),value:this.value.slice(0)});return e}})(); 27 | Bitcoin.Wallet=function(){var e=Bitcoin.Script,t=Bitcoin.TransactionIn,n=Bitcoin.TransactionOut,r=function(){var e=[];this.addressHashes=[],this.txIndex={},this.unspentOuts=[],this.addressPointer=0,this.addKey=function(t,n){t instanceof Bitcoin.ECKey||(t=new Bitcoin.ECKey(t)),e.push(t),n&&("string"==typeof n&&(n=Crypto.util.base64ToBytes(n)),t.setPub(n)),this.addressHashes.push(t.getBitcoinAddress().getHashBase64())},this.addKeys=function(e,t){"string"==typeof e&&(e=e.split(",")),"string"==typeof t&&(t=t.split(","));var n;if(Array.isArray(t)&&e.length==t.length)for(n=0;n=0)break}if(o.compareTo(s)<0)throw new Error("Insufficient funds.");var a=o.subtract(s),f=new Bitcoin.Transaction;for(u=0;u0&&f.addOutput(this.getNextAddress(),a);var l=1;for(u=0;u 0) {hex = parseInt(bin.substr(0, res) , 2).toString(16).concat(hex)} // converts the residual if bin str not devided by 4 116 | return hex; 117 | } 118 | 119 | function hex2bin(hex) { 120 | var bin =""; 121 | for(var i=0; i < hex.length; i++) { 122 | bin += pad(parseInt(hex.substr(i, 1), 16).toString(2), 4, "0"); 123 | } 124 | return bin; 125 | } 126 | 127 | // Function returns uncompressed pubkey, uncompressed address, compressed pubkey annd compressed address 128 | function LegacyAddr(sec_key) { 129 | var hash_str = pad(sec_key, 64, "0"); 130 | var hash = Crypto.util.hexToBytes(hash_str); 131 | eckey = new Bitcoin.ECKey(hash); 132 | eckey_c = new Bitcoin.ECKey(hash); 133 | var curve = getSECCurveByName("secp256k1"); 134 | var pt = curve.getG().multiply(eckey.priv); 135 | eckey_c.pub = getEncoded(pt, true); 136 | eckey_c.pubKeyHash = Bitcoin.Util.sha256ripe160(eckey_c.pub); 137 | var hash160 = eckey.getPubKeyHash(); 138 | var hash160_c = eckey_c.getPubKeyHash(); 139 | 140 | var pubkey = Crypto.util.bytesToHex(getEncoded(pt, false)); 141 | var pubkey_c = Crypto.util.bytesToHex(eckey_c.pub); 142 | var addr = new Bitcoin.Address(hash160); 143 | var addr_c = new Bitcoin.Address(hash160_c); 144 | 145 | return [pubkey, addr, pubkey_c, addr_c]; 146 | } 147 | 148 | // Function add ch="0" to make the exact length 149 | function pad(str, len, ch) { 150 | padding = ''; 151 | for (var i = 0; i < len - str.length; i++) { 152 | padding += ch; 153 | } 154 | return padding + str; 155 | } 156 | 157 | // Function returns compressed or uncompressed public key 158 | function getEncoded(pt, compressed) { 159 | var x = pt.getX().toBigInteger(); 160 | var y = pt.getY().toBigInteger(); 161 | var enc = integerToBytes(x, 32); 162 | if (compressed) { 163 | if (y.isEven()) { 164 | enc.unshift(0x02); 165 | } else { 166 | enc.unshift(0x03); 167 | } 168 | } else { 169 | enc.unshift(0x04); 170 | enc = enc.concat(integerToBytes(y, 32)); 171 | } 172 | return enc; 173 | } 174 | 175 | // Function shows/hides custom private key input form 176 | function DisplayHEXInput() { 177 | if (HEXtick.checked) { 178 | HEXform.style.display = "block"; 179 | } else { 180 | HEXform.style.display = "none"; 181 | } 182 | } 183 | 184 | function visualizeHEX() { 185 | HEXinput.value = HEXinput.value.replace(/ /g, ''); 186 | if (!/[^0123456789abcdef]+/i.test(HEXinput.value) && HEXinput.value != "" && HEXinput.value.length <=64 ) { 187 | BINstring = pad(hex2bin(HEXinput.value), 256, "0"); 188 | for (let i=0; i<16; i++) { 189 | BTCpk[i] = BINstring.substr(i*16, 16).split(""); 190 | } 191 | fillAllfromArr(); 192 | calculation(); 193 | } else { 194 | HEXinput.style.background="#FFFDD0"; 195 | } 196 | } 197 | 198 | function DisplayAdvOptDIV(){ 199 | if (document.getElementById("AdvOpt").checked) { 200 | AdvOptform.style.display = "block"; 201 | } else { 202 | AdvOptform.style.display = "none"; 203 | } 204 | } 205 | 206 | function ChangeExplorer() { 207 | BlockExplorer = document.getElementById("ExplorerSelect").value; 208 | calculation(); 209 | } 210 | 211 | function ClearAll () { 212 | for (let i=0; i<16; i++) { 213 | BTCpk[i] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 214 | } 215 | fillAllfromArr(); 216 | calculation(); 217 | HEXinput.value = ""; 218 | BTCbin.textContent = ""; 219 | BTChex.value = ""; 220 | BTCadd_trans.value = ""; 221 | BTCadd_c_trans.value = ""; 222 | LastCell = [16, 16]; 223 | } 224 | 225 | function rndPrivKey() { 226 | for (var x=0; x<16; x++) {for (var y=0; y<16; y++) { 227 | if (blockX[x] == 0 && blockY[y] == 0) {BTCpk[y][x] = Math.floor(Math.random() * 2)}; 228 | }} 229 | fillAllfromArr(); 230 | calculation(); 231 | LastCell = [16, 16]; 232 | } 233 | 234 | function InverseKey() { 235 | for (var x=0; x<16; x++) {for (var y=0; y<16; y++) { 236 | if (blockX[x] == 0 && blockY[y] == 0) {BTCpk[y][x] ^= 1}; 237 | }} 238 | fillAllfromArr(); 239 | calculation(); 240 | LastCell = [16, 16]; 241 | } 242 | 243 | function RotateKey() { 244 | BTCtmp = JSON.parse(JSON.stringify(BTCpk)); 245 | for (var x=0; x<16; x++) {for (var y=0; y<16; y++) { 246 | BTCpk[y][x] = BTCtmp[15-x][y]; 247 | }} 248 | UnblockLines(); // Rotation also unblocks lines in order to rotate the pattern key and not loose the bits 249 | fillAllfromArr(); 250 | calculation(); 251 | LastCell = [16, 16]; 252 | BTCtmp = []; 253 | } 254 | 255 | function UnblockLines() { 256 | blockX = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 257 | blockY = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 258 | } 259 | 260 | function GenerateExportDIV () { 261 | if (BTChex.value == 0 || BTChex.value == "") {return;} 262 | ExportDIV.style.display = "block"; 263 | ExportPriv.value = BTChex.value; 264 | if (ExportKeyType.value == 1) { 265 | ExportKeyType.value = "0"; 266 | document.getElementById("AddressLabel").innerHTML = "BTC address (Legacy, uncompressed)"; 267 | ExportAddr.value = BTCaddr_gen.value; 268 | var WIF = new Bitcoin.Address(Crypto.util.hexToBytes(BTChex.value)); 269 | WIF.version = 0x80; 270 | ExportWIF.value = WIF.toString(); 271 | } else { 272 | ExportKeyType.value = "1"; 273 | document.getElementById("AddressLabel").innerHTML = "BTC address (Legacy, compressed)"; 274 | ExportAddr.value = BTCaddr_c_gen.value; 275 | var WIF = new Bitcoin.Address(Crypto.util.hexToBytes(BTChex.value + "01")); 276 | WIF.version = 0x80; 277 | ExportWIF.value = WIF.toString(); 278 | } 279 | GenerateQR(); 280 | } 281 | 282 | function GenerateQR () { 283 | var KeyQR = qrcode (4, "M"); 284 | var AddrQR = qrcode (4, "M"); 285 | var textqrKey = ExportWIF.value.replace(/^[\s\u3000]+|[\s\u3000]+$/g, ""); 286 | KeyQR.addData(textqrKey); 287 | KeyQR.make(); 288 | document.getElementById("PrivKeyQR").innerHTML = KeyQR.createImgTag(3); 289 | var textqrAddr = ExportAddr.value.replace(/^[\s\u3000]+|[\s\u3000]+$/g, ""); 290 | AddrQR.addData(textqrAddr); 291 | AddrQR.make(); 292 | document.getElementById("AddressQR").innerHTML = AddrQR.createImgTag(4); 293 | } 294 | 295 | function printDIV() { 296 | var newDIV = document.getElementById("DIVtoPrint").cloneNode(true); 297 | newDIV.id = "PrintDIVclone"; 298 | document.body.appendChild(newDIV); 299 | document.getElementById("MainDIV").classList.add("noPrint"); 300 | document.getElementById("PrintDIVclone").classList.add("printThis"); 301 | window.print(); 302 | document.getElementById("MainDIV").classList.remove("noPrint"); 303 | removeDIV("PrintDIVclone"); 304 | } 305 | 306 | function removeDIV(id) { 307 | var elem = document.getElementById(id); 308 | return elem.parentNode.removeChild(elem); 309 | } 310 | 311 | // Function checks if bin string number within bitcoin order (not more than the order) 312 | function IsInOrder(BinNumStr) { 313 | var t = true; 314 | if (BinNumStr.length > 256) {t = false} else { 315 | if (BinNumStr.length == 256) { 316 | for (let i=0; i<256; i++) { 317 | if (BinNumStr.substr(i,1) > BTCOrderBin[i]) { 318 | return false; } else { 319 | if (BinNumStr.substr(i,1) < BTCOrderBin[i]) {return true;} 320 | } 321 | } 322 | } 323 | } 324 | return t; 325 | } 326 | 327 | // Main script 328 | 329 | // transfers pic key to field and makes calculations 330 | function calculation() { 331 | BTCbin.textContent = PrivFromArr(); 332 | BTChex.value = bin2hex(BTCbin.textContent); 333 | if(!IsInOrder(BTCbin.textContent)) {Caution.style.display = "block";} else {Caution.style.display = "none"}; 334 | if (BTCbin.textContent == 0) { 335 | GenResults = ["", "", "", ""]; 336 | } else { 337 | GenResults = LegacyAddr(BTChex.value); 338 | } 339 | BTCp_gen.textContent = GenResults[0]; 340 | BTCaddr_gen.value = GenResults[1]; 341 | BTCp_c_gen.textContent = GenResults[2]; 342 | BTCaddr_c_gen.value = GenResults[3]; 343 | ExportDIV.style.display = "none"; 344 | document.getElementById("ExploreBTCAddr").href = BlockExplorer + BTCaddr_gen.value; 345 | document.getElementById("ExploreBTCAddrC").href = BlockExplorer + BTCaddr_c_gen.value; 346 | if (document.getElementById("CheckAddrOnline").checked) {AddressCheckOnline(GenResults[1], BTCadd_trans); AddressCheckOnline(GenResults[3], BTCadd_c_trans)}; 347 | } 348 | 349 | // check volume of transactions received by address; no used by default, activated only by advanced options 350 | function AddressCheckOnline(address, fieldForResult) { 351 | if (address != "") { 352 | let xhr = new XMLHttpRequest(); 353 | xhr.open("GET", APIrequestURL+address+"?r="+Math.random(), true); 354 | xhr.timeout = 3000; //timeout for API request 355 | xhr.ontimeout = function () {} 356 | xhr.send(); 357 | xhr.onreadystatechange = function() { 358 | if (xhr.readyState !== 4) return; 359 | if (xhr.status === 200) { 360 | fieldForResult.value = "\u0243" + " " + xhr.responseText/100000000; 361 | if (fieldForResult.value == "\u0243" + " " + "0") {fieldForResult.style.background="none"} else {fieldForResult.style.background="#58fc49"}; 362 | } else { 363 | console.log("HTTP API error on", APIrequestURL, xhr.status, xhr.statusText); 364 | fieldForResult.value = "\u0243" + " " + "0"; 365 | fieldForResult.style.background="none"; 366 | } 367 | } 368 | }} 369 | 370 | // Function returns the X and Y of 16x16 array based on mouse position 371 | function getCellByPosition(X, Y) { 372 | var cellX = Math.floor((X - cell) / cell) 373 | var cellY = Math.floor((Y - cell) / cell) 374 | return [cellX, cellY] 375 | } 376 | 377 | // Function fills/unfills the cell and changes the array element 378 | function fillCell(CellToFill) { 379 | x = CellToFill[0]; 380 | y = CellToFill[1]; 381 | if ((x == -1 || y == -1) && IsLinesBlockOption) {blockLine(x, y)}; 382 | if (x < 0 || y < 0 || x > 15 || y > 15 || (x == LastCell[0] && y == LastCell[1])) {return}; 383 | if (blockX[x] == 1 || blockY[y] == 1) {return}; 384 | if (BTCpk[y][x] == 0) { 385 | colour = cellfillcolour; 386 | BTCpk[y][x] = 1; 387 | } else { 388 | colour = cellnofillcolour; 389 | BTCpk[y][x] = 0; 390 | } 391 | context.fillStyle = colour; 392 | context.fillRect(cell + x * cell, cell + y * cell, cell - 1, cell - 1); 393 | LastCell = [x, y]; 394 | if (timer != 0) {clearTimeout(timer)} 395 | timer = setTimeout(calculation, 200); 396 | } 397 | 398 | function blockLine(row, column) { 399 | if (row == -1 && column == -1) {return}; 400 | if (row == LastCell[0] && column == LastCell[1]) {return}; 401 | if (row == -1) {blockY[column] ^= 1; BTCpk[column] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}; 402 | if (column == -1) {blockX[row] ^= 1; for (var y=0; y<16; y++) {BTCpk[y][row] = 0}}; 403 | LastCell = [row, column]; 404 | fillAllfromArr(); 405 | calculation(); 406 | } 407 | 408 | function LinesBlockSwitch() { 409 | IsLinesBlockOption = document.getElementById("CheckBlockLines").checked; 410 | if (!IsLinesBlockOption) {UnblockLines(); fillAllfromArr()} 411 | } 412 | 413 | function AddHideTransactionsField() { 414 | if (document.getElementById("CheckAddrOnline").checked) { 415 | BTCadd_trans.style.display="inline-block"; 416 | BTCadd_c_trans.style.display="inline-block"; 417 | BTCaddr_gen.style.width="374px"; 418 | BTCaddr_c_gen.style.width="374px"; 419 | setTimeout(calculation, 100); 420 | } 421 | else { 422 | BTCadd_trans.style.display="none"; 423 | BTCadd_c_trans.style.display="none"; 424 | BTCadd_trans.value = ""; 425 | BTCadd_c_trans.value = ""; 426 | BTCaddr_gen.style.width="476px"; 427 | BTCaddr_c_gen.style.width="476px"; 428 | } 429 | } 430 | 431 | function fillAllfromArr() { 432 | for (var x=0; x<16; x++) {for (var y=0; y<16; y++) { 433 | if (BTCpk[y][x] == 1) {colour = cellfillcolour} else {colour = cellnofillcolour}; 434 | if (blockX[x] == 1 || blockY[y] == 1) {colour = cellblockcolour} 435 | context.fillStyle = colour; 436 | context.fillRect(cell + x * cell, cell + y * cell, cell - 1, cell - 1); 437 | }} 438 | } 439 | 440 | function handleMouseDown(event) { 441 | CellXY = getCellByPosition(event.offsetX, event.offsetY); 442 | fillCell(CellXY); 443 | 444 | c_canvas.addEventListener('mousemove', handleMouseMove, false); 445 | } 446 | 447 | function handleMouseMove(event) { 448 | fillCell(getCellByPosition(event.offsetX, event.offsetY)); 449 | } 450 | 451 | function handleMouseUp() { 452 | c_canvas.removeEventListener('mousemove', handleMouseMove, false) 453 | LastCell = [16, 16]; 454 | } 455 | 456 | c_canvas.addEventListener('mousedown', handleMouseDown, false); 457 | c_canvas.addEventListener('mouseup', handleMouseUp, false); 458 | 459 | document.getElementById("ownHEX").addEventListener("change", DisplayHEXInput, false); 460 | document.getElementById("ownHEXbtn").addEventListener("click", visualizeHEX, false); 461 | document.getElementById("ClearButton").addEventListener("click", ClearAll, false); 462 | document.getElementById("RandButton").addEventListener("click", rndPrivKey, false); 463 | document.getElementById("Inverse").addEventListener("click", InverseKey, false); 464 | document.getElementById("Rotate").addEventListener("click", RotateKey, false); 465 | document.getElementById("GenQRbtn").addEventListener("click", GenerateExportDIV, false); 466 | document.getElementById("PrintBtn").addEventListener("click", printDIV, false); 467 | document.getElementById("AdvOpt").addEventListener("change", DisplayAdvOptDIV, false); 468 | document.getElementById("ExplorerSelect").addEventListener("change", ChangeExplorer, false); 469 | document.getElementById("CheckBlockLines").addEventListener("change", LinesBlockSwitch, false); 470 | document.getElementById("CheckAddrOnline").addEventListener("change", AddHideTransactionsField, false); 471 | 472 | ClearAll (); 473 | -------------------------------------------------------------------------------- /robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /css 3 | Disallow: /js 4 | Disallow: /cgi-bin 5 | Disallow: /.git 6 | Host: https://btckeygen.com 7 | Sitemap: http://btckeygen.com/sitemap.xml --------------------------------------------------------------------------------