Skip to content

Commit 4fa4c45

Browse files
committed
Add hash functions for strings, numbers and waves
These uses XXH3-64 for IP10 and CRC for IP9.
1 parent b1ce2ce commit 4fa4c45

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

Packages/MIES/MIES_Constants.ipf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,6 +2318,7 @@ Constant SUBWINDOW_MOVE_CORRECTION = 5
23182318
/// @anchor HashMethods
23192319
///@{
23202320
Constant HASH_SHA2_256 = 1
2321+
Constant HASH_XXH3_64 = 102
23212322
///@}
23222323

23232324
// see DisplayHelpTopic "LoadWave"

Packages/MIES/MIES_Utilities_Algorithm.ipf

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,3 +1275,65 @@ Function FindSequenceReverseWrapper(WAVE sequence, WAVE source)
12751275
start = foundIndex + 1
12761276
endfor
12771277
End
1278+
1279+
/// @brief Return a hash of `str` taking `previousHash` into account
1280+
///
1281+
/// Uses `XXH3-64` on IP10 and CRC on IP9. Can not be used for security purposes.
1282+
threadsafe Function/S HashString(string previousHash, string str)
1283+
1284+
variable crc
1285+
1286+
#if IgorVersion() >= 10
1287+
return Hash(previousHash + str, HASH_XXH3_64)
1288+
#endif
1289+
1290+
if(IsEmpty(previousHash))
1291+
crc = 0
1292+
else
1293+
crc = str2num(previousHash)
1294+
endif
1295+
1296+
#ifdef AUTOMATED_TESTING
1297+
ASSERT_TS(IsFinite(crc), "Expected previousHash to be a number:" + previousHash)
1298+
#endif // AUTOMATED_TESTING
1299+
1300+
return num2istr(StringCRC(crc, str)) // NOLINT
1301+
End
1302+
1303+
/// @brief Return a hash of `wv` taking `previousHash` into account
1304+
///
1305+
/// Uses `XXH3-64` on IP10 and CRC on IP9. Can not be used for security purposes.
1306+
threadsafe Function/S HashWave(string previousHash, WAVE/Z wv)
1307+
1308+
variable crc
1309+
1310+
ASSERT_TS(WaveExists(wv), "Missing wv")
1311+
1312+
#if IgorVersion() >= 10
1313+
return previousHash + WaveHash(wv, HASH_XXH3_64)
1314+
#endif
1315+
1316+
if(IsEmpty(previousHash))
1317+
crc = 0
1318+
else
1319+
crc = str2num(previousHash)
1320+
endif
1321+
1322+
#ifdef AUTOMATED_TESTING
1323+
ASSERT_TS(IsFinite(crc), "Expected previousHash to be a number:" + previousHash)
1324+
#endif // AUTOMATED_TESTING
1325+
1326+
return num2istr(WaveCRC(crc, wv)) // NOLINT
1327+
End
1328+
1329+
/// @brief Return a hash of `num` taking `previousHash` into account
1330+
///
1331+
/// The conversion to string is done with full double precision.
1332+
///
1333+
/// Uses `XXH3-64` on IP10 and CRC on IP9. Can not be used for security purposes.
1334+
threadsafe Function/S HashNumber(string previousHash, variable num)
1335+
1336+
string str = num2strHighPrec(num, precision = MAX_DOUBLE_PRECISION, shorten = 1)
1337+
1338+
return HashString(previousHash, str)
1339+
End

Packages/tests/Basic/UTF_Utils_Algorithm.ipf

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,3 +1326,50 @@ static Function TestFindSequenceReverseWrapper()
13261326
End
13271327

13281328
/// @}
1329+
1330+
static Function TestHashString()
1331+
1332+
#if IgorVersion() >= 10
1333+
CHECK_EQUAL_STR(HashString("", ""), "2d06800538d394c2")
1334+
CHECK_EQUAL_STR(HashString("123", "b"), "3c9cec9e7b5026a6")
1335+
#else
1336+
CHECK_EQUAL_STR(HashString("", ""), "0")
1337+
CHECK_EQUAL_STR(HashString("123", "b"), "3060352845")
1338+
#endif
1339+
1340+
End
1341+
1342+
static Function TestHashNumber()
1343+
1344+
#if IgorVersion() >= 10
1345+
CHECK_EQUAL_STR(HashNumber("", NaN), "bacd09c7db647d0d")
1346+
CHECK_EQUAL_STR(HashNumber("123", 456), "507f6d6059ff79de")
1347+
#else
1348+
CHECK_EQUAL_STR(HashNumber("", NaN), "1810114945")
1349+
CHECK_EQUAL_STR(HashNumber("123", 456), "3909895360")
1350+
#endif
1351+
1352+
End
1353+
1354+
static Function TestHashWave()
1355+
1356+
try
1357+
HashWave("", $"")
1358+
FAIL()
1359+
catch
1360+
CHECK_NO_RTE()
1361+
endtry
1362+
1363+
Make/T/FREE/N=0 empty
1364+
Make/R/FREE some = {456}
1365+
1366+
#if IgorVersion() >= 10
1367+
CHECK_EQUAL_STR(HashWave("", empty), "2d06800538d394c2")
1368+
// outputted hash is prefixed with previousHash (123)
1369+
CHECK_EQUAL_STR(HashWave("123", some), "12338bbb7f4fc6cddb1")
1370+
#else
1371+
CHECK_EQUAL_STR(HashWave("", empty), "0")
1372+
CHECK_EQUAL_STR(HashWave("123", some), "1220402755")
1373+
#endif
1374+
1375+
End

0 commit comments

Comments
 (0)