github.com/XiaoMi/Gaea@v1.2.5/mysql/util.go (about) 1 // Copyright 2016 The kingshard Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 // Copyright 2019 The Gaea Authors. All Rights Reserved. 16 // 17 // Licensed under the Apache License, Version 2.0 (the "License"); 18 // you may not use this file except in compliance with the License. 19 // You may obtain a copy of the License at 20 // 21 // http://www.apache.org/licenses/LICENSE-2.0 22 // 23 // Unless required by applicable law or agreed to in writing, software 24 // distributed under the License is distributed on an "AS IS" BASIS, 25 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 // See the License for the specific language governing permissions and 27 // limitations under the License. 28 29 package mysql 30 31 import ( 32 "crypto/sha1" 33 "crypto/sha256" 34 "math/rand" 35 "time" 36 "unicode/utf8" 37 ) 38 39 var ( 40 dontEscape = byte(255) 41 encodeMap [256]byte 42 ) 43 44 // CalcPassword calculate password hash 45 func CalcPassword(scramble, password []byte) []byte { 46 if len(password) == 0 { 47 return nil 48 } 49 50 // stage1Hash = SHA1(password) 51 crypt := sha1.New() 52 crypt.Write(password) 53 stage1 := crypt.Sum(nil) 54 55 // scrambleHash = SHA1(scramble + SHA1(stage1Hash)) 56 // inner Hash 57 crypt.Reset() 58 crypt.Write(stage1) 59 hash := crypt.Sum(nil) 60 61 // outer Hash 62 crypt.Reset() 63 crypt.Write(scramble) 64 crypt.Write(hash) 65 scramble = crypt.Sum(nil) 66 67 // token = scrambleHash XOR stage1Hash 68 for i := range scramble { 69 scramble[i] ^= stage1[i] 70 } 71 return scramble 72 } 73 74 func CalcCachingSha2Password(salt []byte, password string) []byte { 75 if len(password) == 0 { 76 return nil 77 } 78 // XOR(SHA256(password), SHA256(SHA256(SHA256(password)), salt)) 79 crypt := sha256.New() 80 crypt.Write([]byte(password)) 81 message1 := crypt.Sum(nil) 82 83 crypt.Reset() 84 crypt.Write(message1) 85 message1Hash := crypt.Sum(nil) 86 87 crypt.Reset() 88 crypt.Write(message1Hash) 89 crypt.Write(salt) 90 message2 := crypt.Sum(nil) 91 92 for i := range message1 { 93 message1[i] ^= message2[i] 94 } 95 96 return message1 97 } 98 99 // RandomBuf return random salt, seed must be in the range of ascii 100 func RandomBuf(size int) ([]byte, error) { 101 buf := make([]byte, size) 102 rand.Seed(time.Now().UTC().UnixNano()) 103 min, max := 30, 127 104 for i := 0; i < size; i++ { 105 buf[i] = byte(min + rand.Intn(max-min)) 106 } 107 return buf, nil 108 } 109 110 // Escape remove exceptional character 111 func Escape(sql string) string { 112 dest := make([]byte, 0, 2*len(sql)) 113 114 for i, w := 0, 0; i < len(sql); i += w { 115 runeValue, width := utf8.DecodeRuneInString(sql[i:]) 116 if c := encodeMap[byte(runeValue)]; c == dontEscape { 117 dest = append(dest, sql[i:i+width]...) 118 } else { 119 dest = append(dest, '\\', c) 120 } 121 w = width 122 } 123 124 return string(dest) 125 } 126 127 var encodeRef = map[byte]byte{ 128 '\x00': '0', 129 '\'': '\'', 130 '"': '"', 131 '\b': 'b', 132 '\n': 'n', 133 '\r': 'r', 134 '\t': 't', 135 26: 'Z', // ctl-Z 136 '\\': '\\', 137 } 138 139 type lengthAndDecimal struct { 140 length int 141 decimal int 142 } 143 144 // defaultLengthAndDecimal provides default Flen and Decimal for fields 145 // from CREATE TABLE when they are unspecified. 146 var defaultLengthAndDecimal = map[byte]lengthAndDecimal{ 147 TypeBit: {1, 0}, 148 TypeTiny: {4, 0}, 149 TypeShort: {6, 0}, 150 TypeInt24: {9, 0}, 151 TypeLong: {11, 0}, 152 TypeLonglong: {20, 0}, 153 TypeDouble: {22, -1}, 154 TypeFloat: {12, -1}, 155 TypeNewDecimal: {11, 0}, 156 TypeDuration: {10, 0}, 157 TypeDate: {10, 0}, 158 TypeTimestamp: {19, 0}, 159 TypeDatetime: {19, 0}, 160 TypeYear: {4, 0}, 161 TypeString: {1, 0}, 162 TypeVarchar: {5, 0}, 163 TypeVarString: {5, 0}, 164 TypeTinyBlob: {255, 0}, 165 TypeBlob: {65535, 0}, 166 TypeMediumBlob: {16777215, 0}, 167 TypeLongBlob: {4294967295, 0}, 168 TypeJSON: {4294967295, 0}, 169 TypeNull: {0, 0}, 170 TypeSet: {-1, 0}, 171 TypeEnum: {-1, 0}, 172 } 173 174 // IsIntegerType indicate whether tp is an integer type. 175 func IsIntegerType(tp byte) bool { 176 switch tp { 177 case TypeTiny, TypeShort, TypeInt24, TypeLong, TypeLonglong: 178 return true 179 } 180 return false 181 } 182 183 // GetDefaultFieldLengthAndDecimal returns the default display length (flen) and decimal length for column. 184 // Call this when no Flen assigned in ddl. 185 // or column value is calculated from an expression. 186 // For example: "select count(*) from t;", the column type is int64 and Flen in ResultField will be 21. 187 // See https://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html 188 func GetDefaultFieldLengthAndDecimal(tp byte) (flen int, decimal int) { 189 val, ok := defaultLengthAndDecimal[tp] 190 if ok { 191 return val.length, val.decimal 192 } 193 return -1, -1 194 } 195 196 // defaultLengthAndDecimal provides default Flen and Decimal for fields 197 // from CAST when they are unspecified. 198 var defaultLengthAndDecimalForCast = map[byte]lengthAndDecimal{ 199 TypeString: {0, -1}, // Flen & Decimal differs. 200 TypeDate: {10, 0}, 201 TypeDatetime: {19, 0}, 202 TypeNewDecimal: {11, 0}, 203 TypeDuration: {10, 0}, 204 TypeLonglong: {22, 0}, 205 TypeJSON: {4194304, 0}, // Flen differs. 206 } 207 208 // GetDefaultFieldLengthAndDecimalForCast returns the default display length (flen) and decimal length for casted column 209 // when flen or decimal is not specified. 210 func GetDefaultFieldLengthAndDecimalForCast(tp byte) (flen int, decimal int) { 211 val, ok := defaultLengthAndDecimalForCast[tp] 212 if ok { 213 return val.length, val.decimal 214 } 215 return -1, -1 216 } 217 218 func init() { 219 for i := range encodeMap { 220 encodeMap[i] = dontEscape 221 } 222 for i := range encodeMap { 223 if to, ok := encodeRef[byte(i)]; ok { 224 encodeMap[byte(i)] = to 225 } 226 } 227 }