Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
583e6341
提交
583e6341
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Use shared code between HASH() and ORA_HASH() and make last argument of HASH() optional
上级
789d7322
master
version-1.4.198
无相关合并请求
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
53 行增加
和
21 行删除
+53
-21
help.csv
h2/src/docsrc/help/help.csv
+1
-1
changelog.html
h2/src/docsrc/html/changelog.html
+2
-0
Function.java
h2/src/main/org/h2/expression/Function.java
+35
-20
hash.sql
h2/src/test/org/h2/test/scripts/functions/numeric/hash.sql
+15
-0
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
583e6341
...
...
@@ -3426,7 +3426,7 @@ CALL TRIM(CHAR(0) FROM UTF8TOSTRING(
"
"Functions (Numeric)","HASH","
HASH(algorithmString,
dataBytes, iterationInt
)
HASH(algorithmString,
expression [, iterationInt]
)
","
Calculate the hash value using an algorithm, and repeat this process for a number of iterations.
Currently, the only algorithm supported is SHA256.
...
...
This diff is collapsed.
Click to expand it.
h2/src/docsrc/html/changelog.html
浏览文件 @
583e6341
...
...
@@ -23,6 +23,8 @@ Change Log
<ul>
<li>
Issue #1038: ora_hash function implementation off by one
</li>
<li>
PR #1054: Introduce overflow bit in tx state
</li>
<li>
Issue #1047: Support DISTINCT in custom aggregate functions
</li>
<li>
PR #1051: Atomic change of transaction state
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/Function.java
浏览文件 @
583e6341
...
...
@@ -31,7 +31,6 @@ import org.h2.schema.Schema;
import
org.h2.schema.Sequence
;
import
org.h2.security.BlockCipher
;
import
org.h2.security.CipherFactory
;
import
org.h2.security.SHA256
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.table.Column
;
import
org.h2.table.ColumnResolver
;
...
...
@@ -213,7 +212,7 @@ public class Function extends Expression implements FunctionCall {
addFunction
(
"TRUNCATE"
,
TRUNCATE
,
VAR_ARGS
,
Value
.
NULL
);
// same as TRUNCATE
addFunction
(
"TRUNC"
,
TRUNCATE
,
VAR_ARGS
,
Value
.
NULL
);
addFunction
(
"HASH"
,
HASH
,
3
,
Value
.
BYTES
);
addFunction
(
"HASH"
,
HASH
,
VAR_ARGS
,
Value
.
BYTES
);
addFunction
(
"ENCRYPT"
,
ENCRYPT
,
3
,
Value
.
BYTES
);
addFunction
(
"DECRYPT"
,
DECRYPT
,
3
,
Value
.
BYTES
);
addFunctionNotDeterministic
(
"SECURE_RAND"
,
SECURE_RAND
,
1
,
Value
.
BYTES
);
...
...
@@ -1203,8 +1202,7 @@ public class Function extends Expression implements FunctionCall {
break
;
}
case
HASH:
result
=
ValueBytes
.
getNoCopy
(
getHash
(
v0
.
getString
(),
v1
.
getBytesNoCopy
(),
v2
.
getInt
()));
result
=
getHash
(
v0
.
getString
(),
v1
,
v2
==
null
?
1
:
v2
.
getInt
());
break
;
case
ENCRYPT:
result
=
ValueBytes
.
getNoCopy
(
encrypt
(
v0
.
getString
(),
...
...
@@ -1728,14 +1726,22 @@ public class Function extends Expression implements FunctionCall {
return
newData
;
}
private
static
byte
[]
getHash
(
String
algorithm
,
byte
[]
bytes
,
int
iterations
)
{
private
static
Value
getHash
(
String
algorithm
,
Value
value
,
int
iterations
)
{
if
(!
"SHA256"
.
equalsIgnoreCase
(
algorithm
))
{
throw
DbException
.
getInvalidValueException
(
"algorithm"
,
algorithm
);
}
for
(
int
i
=
0
;
i
<
iterations
;
i
++
)
{
bytes
=
SHA256
.
getHash
(
bytes
,
false
);
if
(
iterations
<=
0
)
{
throw
DbException
.
getInvalidValueException
(
"iterations"
,
iterations
);
}
return
bytes
;
MessageDigest
md
=
hashImpl
(
value
,
"SHA-256"
);
if
(
md
==
null
)
{
return
ValueNull
.
INSTANCE
;
}
byte
[]
b
=
md
.
digest
();
for
(
int
i
=
1
;
i
<
iterations
;
i
++)
{
b
=
md
.
digest
(
b
);
}
return
ValueBytes
.
getNoCopy
(
b
);
}
private
static
String
substring
(
String
s
,
int
start
,
int
length
)
{
...
...
@@ -1951,15 +1957,30 @@ public class Function extends Expression implements FunctionCall {
if
((
seed
&
0xffff_ffff_0000_0000
L
)
!=
0L
)
{
throw
DbException
.
getInvalidValueException
(
"seed"
,
seed
);
}
MessageDigest
md
=
hashImpl
(
value
,
"SHA-1"
);
if
(
md
==
null
)
{
return
ValueNull
.
INSTANCE
;
}
if
(
seed
!=
0L
)
{
byte
[]
b
=
new
byte
[
4
];
Bits
.
writeInt
(
b
,
0
,
(
int
)
seed
);
md
.
update
(
b
);
}
long
hc
=
Bits
.
readLong
(
md
.
digest
(),
0
);
// Strip sign and use modulo operation to get value from 0 to bucket inclusive
return
ValueLong
.
get
((
hc
&
Long
.
MAX_VALUE
)
%
(
bucket
+
1
));
}
private
static
MessageDigest
hashImpl
(
Value
value
,
String
algorithm
)
{
MessageDigest
md
;
switch
(
value
.
getType
())
{
case
Value
.
NULL
:
return
ValueNull
.
INSTANCE
;
return
null
;
case
Value
.
STRING
:
case
Value
.
STRING_FIXED
:
case
Value
.
STRING_IGNORECASE
:
try
{
md
=
MessageDigest
.
getInstance
(
"SHA-1"
);
md
=
MessageDigest
.
getInstance
(
algorithm
);
md
.
update
(
value
.
getString
().
getBytes
(
StandardCharsets
.
UTF_8
));
}
catch
(
Exception
ex
)
{
throw
DbException
.
convert
(
ex
);
...
...
@@ -1968,7 +1989,7 @@ public class Function extends Expression implements FunctionCall {
case
Value
.
BLOB
:
case
Value
.
CLOB
:
try
{
md
=
MessageDigest
.
getInstance
(
"SHA-1"
);
md
=
MessageDigest
.
getInstance
(
algorithm
);
byte
[]
buf
=
new
byte
[
4096
];
try
(
InputStream
is
=
value
.
getInputStream
())
{
for
(
int
r
;
(
r
=
is
.
read
(
buf
))
>
0
;
)
{
...
...
@@ -1981,20 +2002,13 @@ public class Function extends Expression implements FunctionCall {
break
;
default
:
try
{
md
=
MessageDigest
.
getInstance
(
"SHA-1"
);
md
=
MessageDigest
.
getInstance
(
algorithm
);
md
.
update
(
value
.
getBytesNoCopy
());
}
catch
(
Exception
ex
)
{
throw
DbException
.
convert
(
ex
);
}
}
if
(
seed
!=
0L
)
{
byte
[]
b
=
new
byte
[
4
];
Bits
.
writeInt
(
b
,
0
,
(
int
)
seed
);
md
.
update
(
b
);
}
long
hc
=
Bits
.
readLong
(
md
.
digest
(),
0
);
// Strip sign and use modulo operation to get value from 0 to bucket inclusive
return
ValueLong
.
get
((
hc
&
Long
.
MAX_VALUE
)
%
(
bucket
+
1
));
return
md
;
}
private
static
int
makeRegexpFlags
(
String
stringFlags
)
{
...
...
@@ -2082,6 +2096,7 @@ public class Function extends Expression implements FunctionCall {
min
=
1
;
max
=
3
;
break
;
case
HASH:
case
REPLACE:
case
LOCATE:
case
INSTR:
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/numeric/hash.sql
浏览文件 @
583e6341
...
...
@@ -3,8 +3,23 @@
-- Initial Developer: H2 Group
--
call
hash
(
'SHA256'
,
'Hello'
,
0
);
>
exception
call
hash
(
'SHA256'
,
'Hello'
);
>>
185
f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
call
hash
(
'SHA256'
,
'Hello'
,
1
);
>>
185
f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
call
hash
(
'SHA256'
,
stringtoutf8
(
'Hello'
),
1
);
>>
185
f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
CALL
HASH
(
'SHA256'
,
'Password'
,
1000
);
>>
c644a176ce920bde361ac336089b06cc2f1514dfa95ba5aabfe33f9a22d577f0
CALL
HASH
(
'SHA256'
,
STRINGTOUTF8
(
'Password'
),
1000
);
>>
c644a176ce920bde361ac336089b06cc2f1514dfa95ba5aabfe33f9a22d577f0
call
hash
(
'unknown'
,
'Hello'
,
1
);
>
exception
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论