-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add two buildin function ( decode and encode) #7622
Changes from 11 commits
b1b66b7
6406474
be1cdec
93f593a
4e4459a
4356579
bdf038b
0a20e3b
a1af035
86ff091
c3c5de5
5c71833
b69fb8d
761a352
6f2fa41
f9f7c97
304ab49
9e8b06f
d77eec7
70a2ce9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// Copyright 2017 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package encrypt | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
type randStruct struct { | ||
seed1 uint32 | ||
seed2 uint32 | ||
maxValue uint32 | ||
maxValueDbl float64 | ||
} | ||
|
||
// randomInit random generation structure initialization | ||
func (rs *randStruct) randomInit(password []byte, length int) { | ||
// Generate binary hash from raw text string | ||
var nr, add, nr2, tmp uint32 | ||
nr = 1345345333 | ||
add = 7 | ||
nr2 = 0x12345671 | ||
|
||
for i := 0; i < length; i++ { | ||
pswChar := password[i] | ||
if pswChar == ' ' || pswChar == '\t' { | ||
continue | ||
} | ||
tmp = uint32(pswChar) | ||
nr ^= (((nr & 63) + add) * tmp) + (nr << 8) | ||
nr2 += (nr2 << 8) ^ nr | ||
add += tmp | ||
} | ||
|
||
seed1 := nr & ((uint32(1) << 31) - uint32(1)) | ||
seed2 := nr2 & ((uint32(1) << 31) - uint32(1)) | ||
|
||
fmt.Println(seed1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove the debug code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done! Thanks! |
||
fmt.Println(seed2) | ||
|
||
// New (MySQL 3.21+) random generation structure initialization | ||
rs.maxValue = 0x3FFFFFFF | ||
rs.maxValueDbl = float64(rs.maxValue) | ||
rs.seed1 = seed1 % rs.maxValue | ||
rs.seed2 = seed2 % rs.maxValue | ||
} | ||
|
||
func (rs *randStruct) myRand() float64 { | ||
rs.seed1 = (rs.seed1*3 + rs.seed2) % rs.maxValue | ||
rs.seed2 = (rs.seed1 + rs.seed2 + 33) % rs.maxValue | ||
|
||
return ((float64(rs.seed1)) / rs.maxValueDbl) | ||
} | ||
|
||
// SQLCrypt use to store initialization results | ||
type SQLCrypt struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'd better not export struct There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK |
||
rand randStruct | ||
orgRand randStruct | ||
|
||
decodeBuff [256]byte | ||
encodeBuff [256]byte | ||
shift uint32 | ||
} | ||
|
||
func (sc *SQLCrypt) init(password []byte, length int) { | ||
sc.rand.randomInit(password, length) | ||
|
||
for i := 0; i <= 255; i++ { | ||
sc.decodeBuff[i] = byte(i) | ||
} | ||
|
||
for i := 0; i <= 255; i++ { | ||
idx := uint32(sc.rand.myRand() * 255.0) | ||
a := sc.decodeBuff[idx] | ||
sc.decodeBuff[idx] = sc.decodeBuff[i] | ||
sc.decodeBuff[i] = a | ||
} | ||
|
||
for i := 0; i <= 255; i++ { | ||
sc.encodeBuff[sc.decodeBuff[i]] = byte(i) | ||
} | ||
|
||
sc.orgRand = sc.rand | ||
sc.shift = 0 | ||
} | ||
|
||
func (sc *SQLCrypt) reinit() { | ||
sc.shift = 0 | ||
sc.rand = sc.orgRand | ||
} | ||
|
||
func (sc *SQLCrypt) encode(str []byte, length int) { | ||
for i := 0; i < length; i++ { | ||
sc.shift ^= uint32(sc.rand.myRand() * 255.0) | ||
idx := uint32(str[i]) | ||
str[i] = sc.encodeBuff[idx] ^ byte(sc.shift) | ||
sc.shift ^= idx | ||
} | ||
} | ||
|
||
func (sc *SQLCrypt) decode(str []byte, length int) { | ||
for i := 0; i < length; i++ { | ||
sc.shift ^= uint32(sc.rand.myRand() * 255.0) | ||
idx := uint32(str[i] ^ byte(sc.shift)) | ||
str[i] = sc.decodeBuff[idx] | ||
sc.shift ^= uint32(str[i]) | ||
} | ||
} | ||
|
||
//SQLDecode Function to handle the decode() function | ||
func SQLDecode(str string, password string) (string, error) { | ||
var sqlCrypt SQLCrypt | ||
|
||
strByte := []byte(str) | ||
passwdByte := []byte(password) | ||
|
||
sqlCrypt.init(passwdByte, len(passwdByte)) | ||
sqlCrypt.decode(strByte, len(strByte)) | ||
|
||
return string(strByte), nil | ||
} | ||
|
||
// SQLEncode Function to handle the encode() function | ||
func SQLEncode(cryptStr string, password string) (string, error) { | ||
var sqlCrypt SQLCrypt | ||
|
||
cryptStrByte := []byte(cryptStr) | ||
passwdByte := []byte(password) | ||
|
||
sqlCrypt.init(passwdByte, len(passwdByte)) | ||
sqlCrypt.encode(cryptStrByte, len(cryptStrByte)) | ||
|
||
return string(cryptStrByte), nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Copyright 2017 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package encrypt | ||
|
||
import ( | ||
. "github.com/pingcap/check" | ||
"github.com/pingcap/tidb/util/testleak" | ||
) | ||
|
||
func (s *testEncryptSuite) TestSQLDecode(c *C) { | ||
defer testleak.AfterTest(c)() | ||
tests := []struct { | ||
str string | ||
passwd string | ||
expect string | ||
isError bool | ||
}{ | ||
{"", "", "", false}, | ||
{"pingcap", "1234567890123456", "2C35B5A4ADF391", false}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
{"pingcap", "asdfjasfwefjfjkj", "351CC412605905", false}, | ||
{"pingcap123", "123456789012345678901234", "7698723DC6DFE7724221", false}, | ||
{"pingcap#%$%^", "*^%YTu1234567", "8634B9C55FF55E5B6328F449", false}, | ||
{"pingcap", "", "4A77B524BD2C5C", false}, | ||
} | ||
|
||
for _, t := range tests { | ||
crypted, err := SQLDecode(t.str, t.passwd) | ||
if t.isError { | ||
c.Assert(err, NotNil, Commentf("%v", t)) | ||
continue | ||
} | ||
c.Assert(err, IsNil, Commentf("%v", t)) | ||
result := toHex([]byte(crypted)) | ||
c.Assert(result, Equals, t.expect, Commentf("%v", t)) | ||
} | ||
} | ||
|
||
func (s *testEncryptSuite) TestSQLEncode(c *C) { | ||
defer testleak.AfterTest(c)() | ||
tests := []struct { | ||
str string | ||
passwd string | ||
expect string | ||
isError bool | ||
}{ | ||
{"", "", "", false}, | ||
{"pingcap", "1234567890123456", "pingcap", false}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
{"pingcap", "asdfjasfwefjfjkj", "pingcap", false}, | ||
{"pingcap123", "123456789012345678901234", "pingcap123", false}, | ||
{"pingcap#%$%^", "*^%YTu1234567", "pingcap#%$%^", false}, | ||
{"pingcap", "", "pingcap", false}, | ||
} | ||
|
||
for _, t := range tests { | ||
crypted, err := SQLDecode(t.str, t.passwd) | ||
uncrypte, err := SQLEncode(crypted, t.passwd) | ||
|
||
if t.isError { | ||
c.Assert(err, NotNil, Commentf("%v", t)) | ||
continue | ||
} | ||
c.Assert(err, IsNil, Commentf("%v", t)) | ||
c.Assert(uncrypte, Equals, t.expect, Commentf("%v", t)) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add some cases for
NULL
inputs and other conditions, like:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done