├── .gitignore ├── Demo.png ├── Source ├── crc8.vi ├── md5.vi ├── crc16.vi ├── crc32.vi ├── sha256.vi ├── VI Tree.vi ├── adler32.vi ├── hexlify.vi ├── sha256_hmac.vi ├── base64_decode.vi ├── base64_encode.vi ├── random_bytes.vi ├── reverse_bits.vi ├── sha256_pbkdf2.vi ├── sha256_scram_client_final.vi ├── sha256_scram_client_first.vi └── LabVIEW-Hashlib.lvlib ├── Examples └── Demo.vi ├── Tests ├── Test All.vi ├── Test crc16.vi ├── Test crc32.vi ├── Test crc8.vi ├── Test md5.vi ├── Test adler32.vi ├── Test base64.vi ├── Test sha256_hmac.vi └── Test sha256_pbkdf2.vi ├── Builds ├── LabVIEW-Hashlib.lvlibp ├── LabVIEW-Hashlib-LabVIEW 2018.zip └── LabVIEW-Hashlib-LabVIEW 2022.zip ├── LICENSE ├── LabVIEW-Hashlib.lvproj └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Metadata 2 | *.aliases 3 | *.lvlps 4 | 5 | -------------------------------------------------------------------------------- /Demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Demo.png -------------------------------------------------------------------------------- /Source/crc8.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/crc8.vi -------------------------------------------------------------------------------- /Source/md5.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/md5.vi -------------------------------------------------------------------------------- /Examples/Demo.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Examples/Demo.vi -------------------------------------------------------------------------------- /Source/crc16.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/crc16.vi -------------------------------------------------------------------------------- /Source/crc32.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/crc32.vi -------------------------------------------------------------------------------- /Source/sha256.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/sha256.vi -------------------------------------------------------------------------------- /Source/VI Tree.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/VI Tree.vi -------------------------------------------------------------------------------- /Source/adler32.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/adler32.vi -------------------------------------------------------------------------------- /Source/hexlify.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/hexlify.vi -------------------------------------------------------------------------------- /Tests/Test All.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Tests/Test All.vi -------------------------------------------------------------------------------- /Tests/Test crc16.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Tests/Test crc16.vi -------------------------------------------------------------------------------- /Tests/Test crc32.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Tests/Test crc32.vi -------------------------------------------------------------------------------- /Tests/Test crc8.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Tests/Test crc8.vi -------------------------------------------------------------------------------- /Tests/Test md5.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Tests/Test md5.vi -------------------------------------------------------------------------------- /Source/sha256_hmac.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/sha256_hmac.vi -------------------------------------------------------------------------------- /Tests/Test adler32.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Tests/Test adler32.vi -------------------------------------------------------------------------------- /Tests/Test base64.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Tests/Test base64.vi -------------------------------------------------------------------------------- /Source/base64_decode.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/base64_decode.vi -------------------------------------------------------------------------------- /Source/base64_encode.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/base64_encode.vi -------------------------------------------------------------------------------- /Source/random_bytes.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/random_bytes.vi -------------------------------------------------------------------------------- /Source/reverse_bits.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/reverse_bits.vi -------------------------------------------------------------------------------- /Source/sha256_pbkdf2.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/sha256_pbkdf2.vi -------------------------------------------------------------------------------- /Tests/Test sha256_hmac.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Tests/Test sha256_hmac.vi -------------------------------------------------------------------------------- /Builds/LabVIEW-Hashlib.lvlibp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Builds/LabVIEW-Hashlib.lvlibp -------------------------------------------------------------------------------- /Tests/Test sha256_pbkdf2.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Tests/Test sha256_pbkdf2.vi -------------------------------------------------------------------------------- /Source/sha256_scram_client_final.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/sha256_scram_client_final.vi -------------------------------------------------------------------------------- /Source/sha256_scram_client_first.vi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Source/sha256_scram_client_first.vi -------------------------------------------------------------------------------- /Builds/LabVIEW-Hashlib-LabVIEW 2018.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Builds/LabVIEW-Hashlib-LabVIEW 2018.zip -------------------------------------------------------------------------------- /Builds/LabVIEW-Hashlib-LabVIEW 2022.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rcpacini/LabVIEW-Hashlib/HEAD/Builds/LabVIEW-Hashlib-LabVIEW 2022.zip -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Ryan Pacini 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 | -------------------------------------------------------------------------------- /LabVIEW-Hashlib.lvproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 5 | 6 | true 7 | true 8 | false 9 | 0 10 | My Computer/VI Server 11 | My Computer/VI Server 12 | true 13 | true 14 | false 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | true 34 | {48C25002-9BFE-4877-AE74-204CB11815F3} 35 | LabVIEW-Hashlib 36 | true 37 | true 38 | ../Builds 39 | relativeToProject 40 | true 41 | {FDEB54D3-21EB-43FB-8960-E206ED773976} 42 | 2 43 | 1 44 | LabVIEW-Hashlib.lvlibp 45 | ../Builds/NI_AB_PROJECTNAME.lvlibp 46 | relativeToProject 47 | true 48 | App 49 | Support Directory 50 | ../Builds 51 | relativeToProject 52 | 2 53 | true 54 | {CA7D2748-3A2F-43E5-8D78-F5160B89DAB1} 55 | Container 56 | 0 57 | /My Computer/LabVIEW-Hashlib.lvlib 58 | true 59 | true 60 | true 61 | true 62 | TopLevel 63 | Library 64 | 2 65 | Ryan Pacini 66 | true 67 | LabVIEW-Hashlib 68 | LabVIEW-Hashlib 69 | Copyright © 2023 Ryan Pacini 70 | LabVIEW-Hashlib 71 | {7113CB55-23DD-4518-9D9A-8F56AE2F22AE} 72 | LabVIEW-Hashlib.lvlibp 73 | true 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LabVIEW-Hashlib 2 | 3 | Secure hash and message digest algorithms written in plain LabVIEW designed primarily for web application authentication. 4 | 5 | LabVIEW library includes: SHA-256, SCRAM-SHA-256, PBKDF2-SHA-256, HMAC-SHA-256, Base64 encoding/decoding, CRC-8, CRC-16, CRC-32, ADLER-32, and MD5. 6 | 7 | ## Getting Started 8 | 9 | Run the `/Examples/Demo.vi` to demostrate the different hashlib algorithms. 10 | 11 | ![LabVIEW-Hashlib Demo](/Demo.png) 12 | 13 | ## Algorithms 14 | 15 | - **SCRAM-SHA-256** - [RFC 7677](https://datatracker.ietf.org/doc/rfc7677) Simple Authentication and Security Layer Mechanisms (client first and final messages) 16 | - **PBKDF2-SHA-256** - [RFC 2898C](https://tools.ietf.org/html/rfc2898) Salted password-based cryptography 17 | - **HMAC-SHA-256** - [RFC 2104](https://tools.ietf.org/html/rfc2104) Keyed hashing 18 | - **SHA-256** - [RFC 4634](https://tools.ietf.org/html/rfc4634) 256 bit hash 19 | - **Base64** - [RFC 4648](https://tools.ietf.org/html/rfc4648) Encode/decode 20 | - **CRC-8** - [Various CRC-8](https://crccalc.com/) - 8-bit Cyclic Redundancy Check (CRC-8) 21 | - **CRC-16** - [Various CRC-16](https://crccalc.com/) - 16-bit Cyclic Redundancy Check (CRC-16) 22 | - **CRC-32** - [Various CRC-32](https://crccalc.com/) - 32-bit Cyclic Redundancy Check (CRC-32) 23 | - **MD5** - [RFC 1321](https://datatracker.ietf.org/doc/html/rfc1321) - MD5 Message-Digest Algorithm 24 | 32-bit Cyclic Redundancy Check (CRC-32) 25 | - **ADLER-32** - [RFC 1950](https://datatracker.ietf.org/doc/html/rfc1950) - 32-bit Adler checksum for ZLIB 26 | 27 | Refer to the specifications at `https://tools.ietf.org/html/rfcXXXX` . 28 | 29 | ### Acronyms & Abbreviations 30 | 31 | | Key | Name | 32 | | ---------- | ----------------------------------------------------- | 33 | | **SCRAM** | Salted Challenge Response Authentication Mechanism | 34 | | **HMAC** | Keyed-Hashing for Message Authentication | 35 | | **PBKDF2** | Password-Based Cryptography Specification Version 2.0 | 36 | | **SHA** | Secure Hash Algorithm | 37 | | **CRC** | Cyclic Redundancy Check | 38 | | **MD** | Message Digest | 39 | 40 | ### SCRAM-SHA-256 Algorithm 41 | 42 | Refer to [RethinkDB's Writting Drivers](https://rethinkdb.com/docs/writing-drivers/) for a good overview of client side SCRAM-SHA-256 implementation. 43 | 44 | ### CRC-8 Algorithms 45 | 46 | ``` 47 | Data="123456789" 48 | 49 | Algorithm CRC-8 Poly Init RefIn RefOut XorOut 50 | CRC-8 0xF4 0x07 0x00 false false 0x00 51 | CRC-8/CDMA2000 0xDA 0x9B 0xFF false false 0x00 52 | CRC-8/DARC 0x15 0x39 0x00 true true 0x00 53 | CRC-8/DVB-S2 0xBC 0xD5 0x00 false false 0x00 54 | CRC-8/EBU 0x97 0x1D 0xFF true true 0x00 55 | CRC-8/I-CODE 0x7E 0x1D 0xFD false false 0x00 56 | CRC-8/ITU 0xA1 0x07 0x00 false false 0x55 57 | CRC-8/MAXIM 0xA1 0x31 0x00 true true 0x00 58 | CRC-8/ROHC 0xD0 0x07 0xFF true true 0x00 59 | CRC-8/WCDMA 0x25 0x9B 0x00 true true 0x00 60 | ``` 61 | 62 | Source: https://crccalc.com/ 63 | 64 | ### CRC-16 Algorithms 65 | 66 | ``` 67 | Data="123456789" 68 | 69 | Algorithm Result Poly Init RefIn RefOut XorOut 70 | CRC-16/CCITT-FALSE 0x29B1 0x1021 0xFFFF false false 0x0000 71 | CRC-16/ARC 0xBB3D 0x8005 0x0000 true true 0x0000 72 | CRC-16/AUG-CCITT 0xE5CC 0x1021 0x1D0F false false 0x0000 73 | CRC-16/BUYPASS 0xFEE8 0x8005 0x0000 false false 0x0000 74 | CRC-16/CDMA2000 0x4C06 0xC867 0xFFFF false false 0x0000 75 | CRC-16/DDS-110 0x9ECF 0x8005 0x800D false false 0x0000 76 | CRC-16/DECT-R 0x007E 0x0589 0x0000 false false 0x0001 77 | CRC-16/DECT-X 0x007F 0x0589 0x0000 false false 0x0000 78 | CRC-16/DNP 0xEA82 0x3D65 0x0000 true true 0xFFFF 79 | CRC-16/EN-13757 0xC2B7 0x3D65 0x0000 false false 0xFFFF 80 | CRC-16/GENIBUS 0xD64E 0x1021 0xFFFF false false 0xFFFF 81 | CRC-16/MAXIM 0x44C2 0x8005 0x0000 true true 0xFFFF 82 | CRC-16/MCRF4XX 0x6F91 0x1021 0xFFFF true true 0x0000 83 | CRC-16/RIELLO 0x63D0 0x1021 0xB2AA true true 0x0000 84 | CRC-16/T10-DIF 0xD0DB 0x8BB7 0x0000 false false 0x0000 85 | CRC-16/TELEDISK 0x0FB3 0xA097 0x0000 false false 0x0000 86 | CRC-16/TMS37157 0x26B1 0x1021 0x89EC true true 0x0000 87 | CRC-16/USB 0xB4C8 0x8005 0xFFFF true true 0xFFFF 88 | CRC-A 0xBF05 0x1021 0xC6C6 true true 0x0000 89 | CRC-16/KERMIT 0x2189 0x1021 0x0000 true true 0x0000 90 | CRC-16/MODBUS 0x4B37 0x8005 0xFFFF true true 0x0000 91 | CRC-16/X-25 0x906E 0x1021 0xFFFF true true 0xFFFF 92 | CRC-16/XMODEM 0x31C3 0x1021 0x0000 false false 0x0000 93 | ``` 94 | 95 | Source: https://crccalc.com/ 96 | 97 | ### CRC-32 Algorithms 98 | 99 | ``` 100 | Data = "123456789" 101 | 102 | Algorithm CRC-32 Poly Init RefIn RefOut XorOut 103 | CRC-32 0xCBF43926 0x04C11DB7 0xFFFFFFFF true true 0xFFFFFFFF 104 | CRC-32/BZIP2 0xFC891918 0x04C11DB7 0xFFFFFFFF false false 0xFFFFFFFF 105 | CRC-32C 0xE3069283 0x1EDC6F41 0xFFFFFFFF true true 0xFFFFFFFF 106 | CRC-32D 0x87315576 0xA833982B 0xFFFFFFFF true true 0xFFFFFFFF 107 | CRC-32/JAMCRC 0x340BC6D9 0x04C11DB7 0xFFFFFFFF true true 0x00000000 108 | CRC-32/MPEG-2 0x0376E6E7 0x04C11DB7 0xFFFFFFFF false false 0x00000000 109 | CRC-32/POSIX 0x765E7680 0x04C11DB7 0x00000000 false false 0xFFFFFFFF 110 | CRC-32Q 0x3010BF7F 0x814141AB 0x00000000 false false 0x00000000 111 | CRC-32/XFER 0xBD0BE338 0x000000AF 0x00000000 false false 0x00000000 112 | ``` 113 | 114 | Source: https://crccalc.com/ 115 | 116 | ### ADLER-32 Algorithms 117 | 118 | ``` 119 | Data = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" 120 | 121 | ADLER-32: 0x154F215E 122 | ``` 123 | 124 | Source: http://www.unit-conversion.info/texttools/adler-32/ 125 | 126 | ## Development 127 | 128 | ### Build 129 | 130 | Nothing to build or install, just download the Hashlib LabVIEW Library source code. 131 | 132 | _Change Notes:_ 133 | 134 | - Added Adler-32 checksum for zlib 135 | 136 | ### Test 137 | 138 | Run `/Tests/Test All.vi` to verify all algorithms. 139 | 140 | If successful, the **all_passed** boolean should return True. 141 | 142 | ## Support 143 | 144 | Submit a ticket for bug fixes or feature requests. 145 | 146 | -Ryan Pacini 147 | -------------------------------------------------------------------------------- /Source/LabVIEW-Hashlib.lvlib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | )D#!!!!!!!)!"1!&!!!-!%!!!@````]!!!!"!!%!!!)Z!!!*Q(C=\>5RDB."%)8B"S)A>5+-@)5[!)GPY#P5&:Q3/O%!>17,'VD)%>E,C*!W]"7=E=\S4W^ZP9%8*Y!1WBGXV`/GO`JTTXB7'NN<[9XO<WW@@\G>T_PBJ@ED\Q_(6]`L=PDU`'85[#2>'8^/H[N`\H3F`P0_'ZN?NJ@N`^Y_XPQ2`0(@Q3P.$S+;;56,7GC?^N\E*D?ZS5VO]C)P]C)P]C)P]C20]C20]C20]C!0]C!0]C!0]L'4CVTE)I>E*D=4G;+GA/E-2?<.?)T(?)S(1RG0]2C0]2A0871]RG-]RG-]$*0R')`R')`R5'J)0(:S0-:$?27?QF.Y#E`B95I6HA*14&95,IL!5('S_&"Y#E`BY;-+4_%J0)7H](";B;@Q&*\#5XA9-F;FBG<?S@&12IEH]33?R*.Y++X%EXA34_**0%SHR*.Y%E1S96)=AJ*"39@E)0%E(PYI]33?R*.Y%A_HRB8+M4+T:N\*]13?Q".Y!E`AI91#4_!*0)%H]&"7A3@Q"*\!%XC93I%H]!3?!"*-SP1+CA5$AUZ"%(BYD<MFRF7K)9GR3XXTKG^+^=WGPIH5.Y@[IKMPJPICK2>@P;DKR6)PAPL,K>&KD(I3^?#ZIU[](WF\WI[WJ7VI;^K+NK1NZK'`O?0J>.,R?.2_P^>ON^.WO^6GM^&[P>:KN>*SO>2CM8B]$,RH@XQA8*Z,U^X8QX4XZ4#^]Y@JWY`$^0X4Y3`^@`Y(HIV[L;>TM%9`!7D/C--!!!!! 5 | hashlib 6 | 573603840 7 | 1.0.0.0 8 | true 9 | 50 49 48 48 56 48 48 48 13 0 0 0 0 1 23 21 76 111 97 100 32 38 32 85 110 108 111 97 100 46 108 118 99 108 97 115 115 0 0 1 0 0 0 0 0 9 0 0 13 43 1 100 1 100 80 84 72 48 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 15 13 76 97 121 101 114 46 108 118 99 108 97 115 115 0 0 1 0 0 0 0 0 7 0 0 12 191 0 0 0 0 0 0 0 0 0 0 12 158 0 40 0 0 12 152 0 0 12 0 0 0 0 0 0 32 0 32 0 24 0 0 0 0 0 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 0 0 0 0 0 0 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 246 246 246 51 51 51 51 51 51 51 51 51 246 246 246 246 246 246 246 246 246 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 0 0 0 0 0 0 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 0 0 0 0 0 0 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 246 246 246 246 246 246 246 246 246 246 246 246 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 246 246 246 51 51 51 51 51 51 246 246 246 246 246 246 246 246 246 246 246 246 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 0 0 0 0 0 0 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 246 246 246 246 246 246 246 246 246 246 246 246 51 51 51 51 51 51 51 51 51 51 51 51 246 246 246 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 0 0 0 0 0 0 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 246 246 246 246 246 246 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 246 246 246 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 0 0 0 0 0 0 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 77 101 114 103 101 100 32 76 97 121 101 114 115 100 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 83 109 97 108 108 32 70 111 110 116 115 0 1 9 1 0 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | --------------------------------------------------------------------------------