summaryrefslogtreecommitdiff
path: root/app/Factories
diff options
context:
space:
mode:
authorGreg Roach <greg@subaqua.co.uk>2025-01-09 17:38:55 +0000
committerGreg Roach <greg@subaqua.co.uk>2025-01-09 17:41:17 +0000
commit5bf1596e0b049d5627260e02f69a09c66be05add (patch)
tree0f5bdfa73cbaa06dc0820383ad0a3850f7226547 /app/Factories
parent9fb109b2bcf8cbe8e6d7bbe6e417b923ef8dd951 (diff)
downloadwebtrees-5bf1596e0b049d5627260e02f69a09c66be05add.tar.gz
webtrees-5bf1596e0b049d5627260e02f69a09c66be05add.tar.bz2
webtrees-5bf1596e0b049d5627260e02f69a09c66be05add.zip
Fix: #5100, fix: #4828 - _UID fields have wrong checksum. Do not automatically create new when editing.
Diffstat (limited to 'app/Factories')
-rw-r--r--app/Factories/IdFactory.php19
1 files changed, 10 insertions, 9 deletions
diff --git a/app/Factories/IdFactory.php b/app/Factories/IdFactory.php
index cb4786a7a2..302227bd70 100644
--- a/app/Factories/IdFactory.php
+++ b/app/Factories/IdFactory.php
@@ -25,7 +25,9 @@ use Ramsey\Uuid\Uuid;
use function dechex;
use function hexdec;
+use function sprintf;
use function str_pad;
+use function str_split;
use function strtoupper;
use function substr;
@@ -42,7 +44,7 @@ class IdFactory implements IdFactoryInterface
public function uuid(): string
{
try {
- return strtolower(strtr(Uuid::uuid4()->toString(), ['-' => '']));
+ return strtolower(Uuid::uuid4()->toString());
} catch (RandomSourceException) {
// uuid4() can fail if there is insufficient entropy in the system.
return '';
@@ -78,23 +80,22 @@ class IdFactory implements IdFactoryInterface
}
/**
- * @param string $uid exactly 32 hex characters
- *
- * @return string
+ * Based on the C implementation in "GEDCOM Unique Identifiers" by Gordon Clarke, dated 2007-06-08
*/
public function pafUidChecksum(string $uid): string
{
$checksum_a = 0; // a sum of the bytes
$checksum_b = 0; // a sum of the incremental values of $checksum_a
+ foreach (str_split($uid, 2) as $byte) {
+ $checksum_a += hexdec($byte);
+ $checksum_b += $checksum_a;
+ }
for ($i = 0; $i < 32; $i += 2) {
$checksum_a += hexdec(substr($uid, $i, 2));
- $checksum_b += $checksum_a & 0xff;
+ $checksum_b += $checksum_a;
}
- $digit1 = str_pad(dechex($checksum_a), 2, '0', STR_PAD_LEFT);
- $digit2 = str_pad(dechex($checksum_b), 2, '0', STR_PAD_LEFT);
-
- return strtoupper($digit1 . $digit2);
+ return sprintf('%02X%02X', $checksum_a & 0xff, $checksum_b & 0xff);
}
}