-
Notifications
You must be signed in to change notification settings - Fork 1
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
Not all base encodings maintain lexicographic-order #7
Comments
Here's an output of 1 run of the tests that used const before = [
'zkcpMuSTH5Qyms6UNeUzEy', 'zkcpMuSTH5RhYRusw9Aos2', 'zkcpMuSTH5SVXZ7hEnTWYo',
'zkcpMuSTH5TFYUrYfaW8d5', 'zkcpMuSTH5U5amB67CJuEn', 'zkcpMuSTH5UoX55jgxLYJ6',
'zkcpMuSTH5VToqnRqZ5TDm', 'zkcpMuSTH5WDBUrciCYNne', 'zkcpMuSTH5WtGFmdCRb3tU',
'zkcpMuSTH5XhX2HQhaiV1C', 'zkcpMuSTH5YWRR29zmGbbB', 'zkcpMuSUGcAbYFfKACqKSf',
'zkcpMuSUGcBDZQLbRxVPLi', 'zkcpMuSUGcBz7LGXvvE62f', 'zkcpMuSUGcCpebDz2r93qg',
'zkcpMuSUGcDUExCi1WSxyD', 'zkcpMuSUGcEHoyquHbbMQh', 'zkcpMuSUGcEx9r2hU6rxgk',
'zkcpMuSUGcFggSo43U5AYu', 'zkcpMuSUGcGWvB4eoF47q6', 'zkcpMuSUGcHATR4Rb4Qm6D',
'zkcpMuSUGcHsLmRrJHpxvr', 'zkcpMuSUGcJboerZkgG2cW', 'zkcpMuSUGcKMfPt4PPn55G',
'zkcpMuSUGcLBcMxrsUa4A4', 'zkcpMuSUGcLxsyJUWqdDJv', 'zkcpMuSUGcMZAYyeXaDwqq',
'zkcpMuSUGcNPvRMEVmnQwV', 'zkcpMuSUGcP817AAoypmvr', 'zkcpMuSUGcPtGe231pX5yG',
'zkcpMuSUGcQbTcZGuH86hk', 'zkcpMuSUGcRKNDXS6jhvCc', 'zkcpMuSUGcSAN5wPhTYJVA',
'zkcpMuSUGcSpud3wKYfMq5', 'zkcpMuSUGcTXp6EZSSquSb', 'zkcpMuSUGcUKQ4wni8wTY1',
'zkcpMuSUGcV5VDut2nSCcZ', 'zkcpMuSUGcViPPW3knDtGc', 'zkcpMuSUGcWWpbQG3yHbEm',
'zkcpMuSUGcXErpiTPJZ3Ww', 'zkcpMuSUGcY1emU9UbMtzZ', 'zkcpMuSUGcYkaLTM7oTTiF',
'zkcpMuSUGcZYScihhBjBHP', 'zkcpMuSUGcaE1UnuPFAUQV', 'zkcpMu8yZEW76wabV3b3hp',
'zkcpMu8yZEWowitnvSHsT7', 'zkcpMu8yZEXdGUftrimrdn', 'zkcpMu8yZEYEfEBq21arQ4',
'zkcpMu8yZEZ2rZzHGdenWt', 'zkcpMu8yZEZtYbmLQ8rdDe', 'zkcpMu8yZEacbXxgzL9TkZ',
'zkcpMu8yZEbLbVt7qUiDAh', 'zkcpMu8yZEc34AvFsqmiPN', 'zkcpMu8yZEcg2rpRkkZNK7',
'zkcpMu8yZEdRsKBNpcKNLd', 'zkcpMu8yZEeDNG86DD9twf', 'zkcpMu8yZEf3oMtHXjj8q3',
'zkcpMu8yZEfhKkh272YNGB', 'zkcpMu8yZEgX1wAD1mAxwt', 'zkcpMu8yZEhC9EoSSKvzFy',
'zkcpMu8yZEhuHZ9zYsFnVv', 'zkcpMu8yZEiekjCnaQhtf8', 'zkcpMu8yZEjRxY1jyeBvEX',
'zkcpMu8yZEk8Km9v87osnH', 'zkcpMuSVG8v5HZtJMvBqNX', 'zkcpMuSVG8vqZ5HZ2oQ2oA',
'zkcpMuSVG8wdi2NFvMUKBx', 'zkcpMuSVG8xGK3kPdbKRed', 'zkcpMuSVG8y6BqbjKEHT5r',
'zkcpMuSVG8yoUT2qFwSy8F', 'zkcpMuSVG8zWzgwo83AP9P', 'zkcpMuSVG91DkfC6tDagfy',
'zkcpMuSVG925GvnqC1fkdr', 'zkcpMuSVG92fMrnAT72UJb', 'zkcpMuSVG93VYjec6Zu7pH',
'zkcpMuSVG94AnXqMsdgQKU', 'zkcpMuSVG94vScfTeFbkeG', 'zkcpMuSVG95ibzkYjhdsrH',
'zkcpMuSVG96PA4v88n6VRn', 'zkcpMuSVG97FNxp3Jx6bpX', 'zkcpMuSVG97wfXQgXmvCcV',
'zkcpMuSVG98exdYsFqKEbJ', 'zkcpMuSVG99KSPXmR2KJ7w', 'zkcpMuSWFffe3jRbzWLCBx',
'zkcpMuSWFfgGrnkzyryHgZ', 'zkcpMuSWFfh8uHbZNhKggy', 'zkcpMuSWFfhqzdV4Mre24h',
'zkcpMuSWFfiY8Ysy6Fk88N', 'zkcpMuSWFfjMy3qN6uzsoz', 'zkcpMuSWFfjz7yUobzjEJ3',
'zkcpMuSWFfksLia9Rcfzup', 'zkcpMuSWFfmZXuDi6YMSit', 'zkcpMuSWFfnEyHAHESWEWD',
'zkcpMuSWFfnwRkdJY8uDvK', 'zkcpMuSWFfofz5CUsb2v7D', 'zkcpMuSWFfpUUPUXYboULf',
'zkcpMuSWFfq8TvJyuSnzqy', 'zkcpMuSWFfqzQt7U5PTUYW', 'zkcpMuSWFfritht74m4uBv',
'zkcpMuSWFfsMjc1zgLsfoc'
];
const sorted = [
'zkcpMu8yZEW76wabV3b3hp', 'zkcpMu8yZEWowitnvSHsT7', 'zkcpMu8yZEXdGUftrimrdn',
'zkcpMu8yZEYEfEBq21arQ4', 'zkcpMu8yZEZ2rZzHGdenWt', 'zkcpMu8yZEZtYbmLQ8rdDe',
'zkcpMu8yZEacbXxgzL9TkZ', 'zkcpMu8yZEbLbVt7qUiDAh', 'zkcpMu8yZEc34AvFsqmiPN',
'zkcpMu8yZEcg2rpRkkZNK7', 'zkcpMu8yZEdRsKBNpcKNLd', 'zkcpMu8yZEeDNG86DD9twf',
'zkcpMu8yZEf3oMtHXjj8q3', 'zkcpMu8yZEfhKkh272YNGB', 'zkcpMu8yZEgX1wAD1mAxwt',
'zkcpMu8yZEhC9EoSSKvzFy', 'zkcpMu8yZEhuHZ9zYsFnVv', 'zkcpMu8yZEiekjCnaQhtf8',
'zkcpMu8yZEjRxY1jyeBvEX', 'zkcpMu8yZEk8Km9v87osnH', 'zkcpMuSTH5Qyms6UNeUzEy',
'zkcpMuSTH5RhYRusw9Aos2', 'zkcpMuSTH5SVXZ7hEnTWYo', 'zkcpMuSTH5TFYUrYfaW8d5',
'zkcpMuSTH5U5amB67CJuEn', 'zkcpMuSTH5UoX55jgxLYJ6', 'zkcpMuSTH5VToqnRqZ5TDm',
'zkcpMuSTH5WDBUrciCYNne', 'zkcpMuSTH5WtGFmdCRb3tU', 'zkcpMuSTH5XhX2HQhaiV1C',
'zkcpMuSTH5YWRR29zmGbbB', 'zkcpMuSUGcAbYFfKACqKSf', 'zkcpMuSUGcBDZQLbRxVPLi',
'zkcpMuSUGcBz7LGXvvE62f', 'zkcpMuSUGcCpebDz2r93qg', 'zkcpMuSUGcDUExCi1WSxyD',
'zkcpMuSUGcEHoyquHbbMQh', 'zkcpMuSUGcEx9r2hU6rxgk', 'zkcpMuSUGcFggSo43U5AYu',
'zkcpMuSUGcGWvB4eoF47q6', 'zkcpMuSUGcHATR4Rb4Qm6D', 'zkcpMuSUGcHsLmRrJHpxvr',
'zkcpMuSUGcJboerZkgG2cW', 'zkcpMuSUGcKMfPt4PPn55G', 'zkcpMuSUGcLBcMxrsUa4A4',
'zkcpMuSUGcLxsyJUWqdDJv', 'zkcpMuSUGcMZAYyeXaDwqq', 'zkcpMuSUGcNPvRMEVmnQwV',
'zkcpMuSUGcP817AAoypmvr', 'zkcpMuSUGcPtGe231pX5yG', 'zkcpMuSUGcQbTcZGuH86hk',
'zkcpMuSUGcRKNDXS6jhvCc', 'zkcpMuSUGcSAN5wPhTYJVA', 'zkcpMuSUGcSpud3wKYfMq5',
'zkcpMuSUGcTXp6EZSSquSb', 'zkcpMuSUGcUKQ4wni8wTY1', 'zkcpMuSUGcV5VDut2nSCcZ',
'zkcpMuSUGcViPPW3knDtGc', 'zkcpMuSUGcWWpbQG3yHbEm', 'zkcpMuSUGcXErpiTPJZ3Ww',
'zkcpMuSUGcY1emU9UbMtzZ', 'zkcpMuSUGcYkaLTM7oTTiF', 'zkcpMuSUGcZYScihhBjBHP',
'zkcpMuSUGcaE1UnuPFAUQV', 'zkcpMuSVG8v5HZtJMvBqNX', 'zkcpMuSVG8vqZ5HZ2oQ2oA',
'zkcpMuSVG8wdi2NFvMUKBx', 'zkcpMuSVG8xGK3kPdbKRed', 'zkcpMuSVG8y6BqbjKEHT5r',
'zkcpMuSVG8yoUT2qFwSy8F', 'zkcpMuSVG8zWzgwo83AP9P', 'zkcpMuSVG91DkfC6tDagfy',
'zkcpMuSVG925GvnqC1fkdr', 'zkcpMuSVG92fMrnAT72UJb', 'zkcpMuSVG93VYjec6Zu7pH',
'zkcpMuSVG94AnXqMsdgQKU', 'zkcpMuSVG94vScfTeFbkeG', 'zkcpMuSVG95ibzkYjhdsrH',
'zkcpMuSVG96PA4v88n6VRn', 'zkcpMuSVG97FNxp3Jx6bpX', 'zkcpMuSVG97wfXQgXmvCcV',
'zkcpMuSVG98exdYsFqKEbJ', 'zkcpMuSVG99KSPXmR2KJ7w', 'zkcpMuSWFffe3jRbzWLCBx',
'zkcpMuSWFfgGrnkzyryHgZ', 'zkcpMuSWFfh8uHbZNhKggy', 'zkcpMuSWFfhqzdV4Mre24h',
'zkcpMuSWFfiY8Ysy6Fk88N', 'zkcpMuSWFfjMy3qN6uzsoz', 'zkcpMuSWFfjz7yUobzjEJ3',
'zkcpMuSWFfksLia9Rcfzup', 'zkcpMuSWFfmZXuDi6YMSit', 'zkcpMuSWFfnEyHAHESWEWD',
'zkcpMuSWFfnwRkdJY8uDvK', 'zkcpMuSWFfofz5CUsb2v7D', 'zkcpMuSWFfpUUPUXYboULf',
'zkcpMuSWFfq8TvJyuSnzqy', 'zkcpMuSWFfqzQt7U5PTUYW', 'zkcpMuSWFfritht74m4uBv',
'zkcpMuSWFfsMjc1zgLsfoc'
]; The problem here is that The base58btc alphabet indicates that it is in lexicographic order though... https://github.com/multiformats/js-multiformats/blob/master/src/bases/base58.js#L6
There might be something I'm forgetting here. |
I'm a bit confused here, the base58btc alphabet is in lexicographic order, but the above is where the error occurred. It seems there's more to preserving lexicographic order than just having the right alphabet order. The link https://www.codeproject.com/Articles/5165340/Sortable-Base64-Encoding says that there's more to it. It could also be due to JS's sorting algorithm is doing something strange. I'm going to try to decode those back to ids, to confirm that they are in fact the right order with buffer comparison and see what the difference is between base58btc and doing hex encoding which should preserve order. |
So after some tests, I've found that:
|
Ok there's a bug inside Here's a script that after running some time, will eventually find an error: import { extractTs, extractSeq } from './src/IdSortable';
import { IdSortable, utils } from './src';
const idGen = new IdSortable();
const findTheProblem = () => {
let count = 100;
while (count > 0) {
const ids = [...utils.take(idGen, 100)];
const ids_ = ids.slice();
ids_.sort(Buffer.compare);
for (let i = 0; i < 100; i++) {
if (ids[i].toString() !== ids_[i].toString()) {
console.log('FOUND AN INEQUALITY');
console.log('COUNT', count);
console.log('INDEX', i);
console.log('ORIGINAL', ids[i]);
console.log('SORTED', ids_[i]);
console.log('ORIGINAL', extractTs(ids[i]), extractSeq(ids[i]));
console.log('SORTED', extractTs(ids_[i]), extractSeq(ids_[i]));
return [ids, ids_];
}
}
count--;
}
return [[], []];
};
const [ids, ids_] = findTheProblem();
console.log(ids.map((id) => utils.toMultibase(id, 'base58btc')));
console.log(ids_.map((id) => utils.toMultibase(id, 'base58btc'))); In my case I found it after generating more than 900 ids. The problem looks like this:
This shows that at index 0, the id provided by the As you can see the extracted TS in seconds and subseconds is When extracting the TS, we are getting |
Neither decoding nor encoding is the problem. The problem is the See here are 2 ids generated one after another, and see how the encoded
|
An The To fix this, we have to fix the rounding occurring in The maximum msec that |
This is now fixed. My tests show that @joshuakarp this should be reminded to go into our reference documentation. |
Specification
It turns out that not all base encodings maintain lexicographic-order. For example base64 and base58 have alphabets that do not preserve order.
After some random testing, I found that the existing test case fails very rarely:
encoded multibase strings are lexically sortable
.I believe this applies to the base encoding but not to the binary string encoding.
Therefore that test doesn't make sense, it makes more sense to identify which base encodings are lexicographic order, and create separate tests for those.
In our README.md it will be important to state that some base encodings will lose the lexicographic order, and provide a selection of the encodings that will maintain order.
Additional context
Tasks
IdSortable
should be using lexicographic order preserving base encodings if need beThe text was updated successfully, but these errors were encountered: