mirror of https://gitee.com/bigwinds/arangodb
add AQL functions CRC32 and FNV64 (#8600)
This commit is contained in:
parent
e0ebfefddd
commit
14720b85be
|
@ -1,6 +1,8 @@
|
|||
devel
|
||||
-----
|
||||
|
||||
* added AQL functions CRC32 and FNV64 for hashing data
|
||||
|
||||
* renamed attribute key `openssl-version` in server/client tool version
|
||||
details output to `openssl-version-compile-time`.
|
||||
|
||||
|
|
|
@ -211,9 +211,11 @@ documents are the same, or for grouping values in queries.
|
|||
|
||||
See the following string functions:
|
||||
|
||||
- [CRC32()](String.md#crc32)
|
||||
- [FNV64()](String.md#fnv64)
|
||||
- [MD5()](String.md#md5)
|
||||
- [SHA1()](String.md#sha1)
|
||||
- [SHA512()](String.md#sha512)
|
||||
- [MD5()](String.md#md5)
|
||||
|
||||
Function calling
|
||||
----------------
|
||||
|
|
|
@ -113,6 +113,22 @@ COUNT()
|
|||
|
||||
This is an alias for [LENGTH()](#length).
|
||||
|
||||
CRC32()
|
||||
-----
|
||||
|
||||
`CRC32(text) → hash`
|
||||
|
||||
Calculate the CRC32 checksum for *text* and return it in a hexadecimal
|
||||
string representation. The polynomial used is 0x1EDC6F41. The initial
|
||||
value used is 0xFFFFFFFF, and the final xor value is also 0xFFFFFFFF.
|
||||
|
||||
- **text** (string): a string
|
||||
- returns **hash** (string): CRC32 checksum as hex string
|
||||
|
||||
```js
|
||||
CRC32("foobar") // "D5F5C7F"
|
||||
```
|
||||
|
||||
ENCODE_URI_COMPONENT()
|
||||
-----------
|
||||
|
||||
|
@ -170,6 +186,21 @@ FIND_LAST("foobarbaz", "ba", 7) // -1
|
|||
FIND_LAST("foobarbaz", "ba", 0, 4) // 3
|
||||
```
|
||||
|
||||
FNV64()
|
||||
-----
|
||||
|
||||
`FNV64(text) → hash`
|
||||
|
||||
Calculate the FNV-1A 64 bit hash for *text* and return it in a hexadecimal
|
||||
string representation.
|
||||
|
||||
- **text** (string): a string
|
||||
- returns **hash** (string): FNV-1A hash as hex string
|
||||
|
||||
```js
|
||||
FNV64("foobar") // "85944171F73967E8"
|
||||
```
|
||||
|
||||
JSON_PARSE()
|
||||
------------
|
||||
|
||||
|
|
|
@ -204,6 +204,8 @@ void AqlFunctionFeature::addStringFunctions() {
|
|||
add({"MD5", ".", flags, &Functions::Md5});
|
||||
add({"SHA1", ".", flags, &Functions::Sha1});
|
||||
add({"SHA512", ".", flags, &Functions::Sha512});
|
||||
add({"CRC32", ".", flags, &Functions::Crc32});
|
||||
add({"FNV64", ".", flags, &Functions::Fnv64});
|
||||
add({"HASH", ".", flags, &Functions::Hash});
|
||||
add({"TO_BASE64", ".", flags, &Functions::ToBase64});
|
||||
add({"TO_HEX", ".", flags, &Functions::ToHex});
|
||||
|
|
|
@ -39,7 +39,9 @@
|
|||
#include "Basics/Utf8Helper.h"
|
||||
#include "Basics/VPackStringBufferAdapter.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Basics/conversions.h"
|
||||
#include "Basics/fpconv.h"
|
||||
#include "Basics/hashes.h"
|
||||
#include "Basics/tri-strings.h"
|
||||
#include "Geo/GeoJson.h"
|
||||
#include "Geo/GeoParams.h"
|
||||
|
@ -4191,6 +4193,36 @@ AqlValue Functions::Sha512(ExpressionContext*, transaction::Methods* trx,
|
|||
return AqlValue(&hex[0], 128);
|
||||
}
|
||||
|
||||
/// @brief function Crc32
|
||||
AqlValue Functions::Crc32(ExpressionContext*, transaction::Methods* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue const& value = extractFunctionParameterValue(parameters, 0);
|
||||
transaction::StringBufferLeaser buffer(trx);
|
||||
arangodb::basics::VPackStringBufferAdapter adapter(buffer->stringBuffer());
|
||||
|
||||
::appendAsString(trx, adapter, value);
|
||||
|
||||
uint32_t crc = TRI_Crc32HashPointer(buffer->c_str(), buffer->length());
|
||||
char out[9];
|
||||
size_t length = TRI_StringUInt32HexInPlace(crc, &out[0]);
|
||||
return AqlValue(&out[0], length);
|
||||
}
|
||||
|
||||
/// @brief function Fnv64
|
||||
AqlValue Functions::Fnv64(ExpressionContext*, transaction::Methods* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue const& value = extractFunctionParameterValue(parameters, 0);
|
||||
transaction::StringBufferLeaser buffer(trx);
|
||||
arangodb::basics::VPackStringBufferAdapter adapter(buffer->stringBuffer());
|
||||
|
||||
::appendAsString(trx, adapter, value);
|
||||
|
||||
uint64_t hash = TRI_FnvHashPointer(buffer->c_str(), buffer->length());
|
||||
char out[17];
|
||||
size_t length = TRI_StringUInt64HexInPlace(hash, &out[0]);
|
||||
return AqlValue(&out[0], length);
|
||||
}
|
||||
|
||||
/// @brief function HASH
|
||||
AqlValue Functions::Hash(ExpressionContext*, transaction::Methods* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
|
|
|
@ -270,6 +270,10 @@ struct Functions {
|
|||
VPackFunctionParameters const&);
|
||||
static AqlValue Sha512(arangodb::aql::ExpressionContext*,
|
||||
transaction::Methods*, VPackFunctionParameters const&);
|
||||
static AqlValue Crc32(arangodb::aql::ExpressionContext*, transaction::Methods*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue Fnv64(arangodb::aql::ExpressionContext*, transaction::Methods*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue Hash(arangodb::aql::ExpressionContext*, transaction::Methods*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue IsKey(arangodb::aql::ExpressionContext*,
|
||||
|
|
|
@ -523,9 +523,5 @@ uint32_t TRI_Crc32HashPointer(void const* data, size_t length) {
|
|||
|
||||
/// @brief computes a CRC32 for strings
|
||||
uint32_t TRI_Crc32HashString(char const* data) {
|
||||
size_t len = strlen(data);
|
||||
|
||||
uint32_t crc = TRI_InitialCrc32();
|
||||
crc = (*TRI_BlockCrc32)(crc, data, len);
|
||||
return TRI_FinalCrc32(crc);
|
||||
return TRI_Crc32HashPointer(data, strlen(data));
|
||||
}
|
||||
|
|
|
@ -60,9 +60,11 @@ extern uint32_t (*TRI_BlockCrc32)(uint32_t hash, char const* data, size_t length
|
|||
}
|
||||
|
||||
/// @brief computes a CRC32 for memory blobs
|
||||
/// the polynomial used is 0x1EDC6F41.
|
||||
uint32_t TRI_Crc32HashPointer(void const*, size_t);
|
||||
|
||||
/// @brief computes a CRC32 for strings
|
||||
/// the polynomial used is 0x1EDC6F41.
|
||||
uint32_t TRI_Crc32HashString(char const*);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2513,6 +2513,34 @@ function ahuacatlStringFunctionsTestSuite () {
|
|||
assertEqual([ '888227c44807b86059eb36f9fe0fc602a9b16fab' ], getQueryResults(`RETURN NOOPT(SHA1('[1,2,4,7,11,16,22,29,37,46,56,67,79,92,106,121,137,154,172,191,211,232,254,277,301,326,352,379,407,436,466,497,529,562,596,631,667,704,742,781,821,862,904,947,991,1036,1082,1129,1177,1226,1276,1327,1379,1432,1486,1541,1597,1654,1712,1771,1831,1892,1954,2017,2081,2146,2212,2279,2347,2416,2486,2557,2629,2702,2776,2851,2927,3004,3082,3161,3241,3322,3404,3487,3571,3656,3742,3829,3917,4006,4096,4187,4279,4372,4466,4561,4657,4754,4852,4951]'))`));
|
||||
},
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief test crc32 function
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCrc32: function () {
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, 'RETURN NOOPT(CRC32())');
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, 'RETURN NOOPT(CRC32("foo", 2))');
|
||||
assertEqual([ '0' ], getQueryResults(`RETURN NOOPT(CRC32(''))`));
|
||||
assertEqual([ '72C0DD8F' ], getQueryResults(`RETURN NOOPT(CRC32(' '))`));
|
||||
assertEqual([ '629E1AE0' ], getQueryResults(`RETURN NOOPT(CRC32('0'))`));
|
||||
assertEqual([ '90F599E3' ], getQueryResults(`RETURN NOOPT(CRC32('1'))`));
|
||||
assertEqual([ '89614B3B' ], getQueryResults(`RETURN NOOPT(CRC32('This is a test string'))`));
|
||||
assertEqual([ 'CC778246' ], getQueryResults(`RETURN NOOPT(CRC32('With\r\nLinebreaks\n'))`));
|
||||
assertEqual([ '0' ], getQueryResults(`RETURN NOOPT(CRC32(null))`));
|
||||
},
|
||||
|
||||
testFnv64: function () {
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, 'RETURN NOOPT(FNV64())');
|
||||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, 'RETURN NOOPT(FNV64("foo", 2))');
|
||||
assertEqual([ 'CBF29CE484222325' ], getQueryResults(`RETURN NOOPT(FNV64(''))`));
|
||||
assertEqual([ 'AF639D4C8601817F' ], getQueryResults(`RETURN NOOPT(FNV64(' '))`));
|
||||
assertEqual([ 'AF63AD4C86019CAF' ], getQueryResults(`RETURN NOOPT(FNV64('0'))`));
|
||||
assertEqual([ 'AF63AC4C86019AFC' ], getQueryResults(`RETURN NOOPT(FNV64('1'))`));
|
||||
assertEqual([ 'D94D32CC2E5C3409' ], getQueryResults(`RETURN NOOPT(FNV64('This is a test string'))`));
|
||||
assertEqual([ 'AF870D34E69ABE0A' ], getQueryResults(`RETURN NOOPT(FNV64('With\r\nLinebreaks\n'))`));
|
||||
assertEqual([ 'CBF29CE484222325' ], getQueryResults(`RETURN NOOPT(FNV64(null))`));
|
||||
},
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief test random_token function
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue