From 7a2de3edff32ab9b26ba00bbff9770b62683bbde Mon Sep 17 00:00:00 2001 From: Suzanne Soy Date: Thu, 16 Nov 2023 23:48:06 +0000 Subject: [PATCH] Turns out I was lucky with my vanity text, not all characters are possible for the last character of the IPFS hash --- directory_hashes.js | 2 +- find_vanity.js | 2 +- ipfs-add.sh | 2 +- micro_ipfs.js | 52 +++++++++++++++++++++++++++++++------- update_directory_hashes.sh | 14 +++++----- 5 files changed, 54 insertions(+), 18 deletions(-) mode change 100644 => 100755 ipfs-add.sh diff --git a/directory_hashes.js b/directory_hashes.js index ea0cb0f..b0a0ff6 100644 --- a/directory_hashes.js +++ b/directory_hashes.js @@ -1 +1 @@ -jsonp_ipfs_directory_hashes({"vanity_text":"soy","vanity_number":4686,"tree":{"Links":[{"Name":".gitignore","Hash":"QmW9iMXzmPqLSnzL4p6DKsvsL3nC1xKS3teRB4SRdukfrz","Size":16},{"Name":".ipfsignore","Hash":"QmWMeSQQxuSYMddVwJGrnn12zrX1TTW7ueZbhZdaZ64Wr1","Size":14},{"Name":"directory_hashes.js","Hash":"","Size":0},{"Name":"find_vanity.js","Hash":"QmZVGHM7i74w275noxHhuLRWmJFTVjzTeXUdzamYaLTXAQ","Size":354},{"Name":"flake.lock","Hash":"QmV1UZtzknzjmyaJyvR7NHFCJ15FbFbS9bHBxTfyRMuNqg","Size":519},{"Name":"flake.nix","Hash":"QmZhzTNT98Z5z7MSJMUDo4A3AMtRFVEBx4paH5GJKharEL","Size":856},{"Name":"index.html","Hash":"QmZaXPFa47VxJNsNcaejw7R9GNPGCF5FjkSCDrvrmBAeP9","Size":553},{"Name":"ipfs-add.sh","Hash":"QmTptVSLh5gqRqUcHrKcv2fdVgY2UmPbwftwQHzSDeqACF","Size":173},{"Name":"lzw.js","Hash":"QmP2CsTDmyR9h5UrXJgXGswyMhiSHBZkQKLszdgh9Eb8Rk","Size":2034},{"Name":"micro_ipfs.js","Hash":"QmcMJvWL45dHLwaL36AeM2NG6xrzudtmTN7mCpt3cuKnnX","Size":15515},{"Name":"quine.js","Hash":"QmcHWTtgH53KkaSsWEvTxKDuuTNxipC3iJyebS3BBuF21B","Size":3099},{"Name":"result","Hash":"QmeG1ZJKGVenSC1VBx9D1nzv1bma7zHMHGMp6nUL5izs9i","Size":73},{"Name":"robots.txt","Hash":"QmSqhdBa5ryzgjN41hL8rM98hjunXashEuLRW8PnKLH5yq","Size":49},{"Name":"sha256.js","Hash":"QmRhgx5Fq4JqfCgsPcMxNSYwt8M9WRBkec9omPWzJ7gdwL","Size":8553},{"Name":"sitemap.txt","Hash":"QmWsbCRCFoLa7AKdHmx8Mt6nV1jxpqEjdbAxZp1pH7tZQr","Size":548},{"Name":"update_directory_hashes.sh","Hash":"QmbgPpzKC6vNxsnKUvZSjCtUmTofwRxJKdKQ6pJFpGWRgC","Size":1695},{"Name":"update_quine.sh","Hash":"QmVZY9bqdiopA4BaxNRwJr5AWLbE8ikb19dAJoKCNENNez","Size":3029}],"Data":"\b\u0001"}}); +jsonp_ipfs_directory_hashes({"vanity_text":"soy","vanity_number":11763,"tree":{"Links":[{"Name":".gitignore","Hash":"QmW9iMXzmPqLSnzL4p6DKsvsL3nC1xKS3teRB4SRdukfrz","Size":16},{"Name":".ipfsignore","Hash":"QmWMeSQQxuSYMddVwJGrnn12zrX1TTW7ueZbhZdaZ64Wr1","Size":14},{"Name":"directory_hashes.js","Hash":"","Size":0},{"Name":"find_vanity.js","Hash":"QmVrVdE8TP4Di1h39LTtDCmDSFRgy7FQnZWrSBPdDHy8Hx","Size":358},{"Name":"flake.lock","Hash":"QmV1UZtzknzjmyaJyvR7NHFCJ15FbFbS9bHBxTfyRMuNqg","Size":519},{"Name":"flake.nix","Hash":"QmZhzTNT98Z5z7MSJMUDo4A3AMtRFVEBx4paH5GJKharEL","Size":856},{"Name":"index.html","Hash":"QmZaXPFa47VxJNsNcaejw7R9GNPGCF5FjkSCDrvrmBAeP9","Size":553},{"Name":"ipfs-add.sh","Hash":"QmPvQrob4PzEJXwxEVhBHEXjnESsMR2f7LJ1nbfAoo8A6G","Size":169},{"Name":"lzw.js","Hash":"QmP2CsTDmyR9h5UrXJgXGswyMhiSHBZkQKLszdgh9Eb8Rk","Size":2034},{"Name":"micro_ipfs.js","Hash":"QmeWPj4vzN66eCUwQkjjzTgfciBLBzNjQQdvqEBL8x1pmh","Size":16738},{"Name":"quine.js","Hash":"QmcHWTtgH53KkaSsWEvTxKDuuTNxipC3iJyebS3BBuF21B","Size":3099},{"Name":"result","Hash":"QmYaABXhasB9Vyn8Sk3KkixsKp4yvXxaCwmXGxFCHGCwwr","Size":73},{"Name":"robots.txt","Hash":"QmSqhdBa5ryzgjN41hL8rM98hjunXashEuLRW8PnKLH5yq","Size":49},{"Name":"sha256.js","Hash":"QmRhgx5Fq4JqfCgsPcMxNSYwt8M9WRBkec9omPWzJ7gdwL","Size":8553},{"Name":"sitemap.txt","Hash":"QmWsbCRCFoLa7AKdHmx8Mt6nV1jxpqEjdbAxZp1pH7tZQr","Size":548},{"Name":"update_directory_hashes.sh","Hash":"QmQLSE6rJCSeKfgM7U3hKanRMfdcaUWSxwXd1wa39iS6qC","Size":1780},{"Name":"update_quine.sh","Hash":"QmVZY9bqdiopA4BaxNRwJr5AWLbE8ikb19dAJoKCNENNez","Size":3029}],"Data":"\b\u0001"}}); diff --git a/find_vanity.js b/find_vanity.js index 92bb1d7..242ed5a 100644 --- a/find_vanity.js +++ b/find_vanity.js @@ -2,4 +2,4 @@ const fs = require("fs"); const micro_ipfs = require('./micro_ipfs.js'); const jsonp = fs.readFileSync(process.argv[2], 'utf-8'); const directory_hashes = JSON.parse(jsonp.substring('jsonp_ipfs_directory_hashes('.length, jsonp.length - ');\n'.length)); -console.log(micro_ipfs.ipfs_self_hash.find_vanity_node(null, process.argv[3], 0, directory_hashes)); \ No newline at end of file +console.log(micro_ipfs.ipfs_self_hash.find_vanity_node(process.argv[3], 0, directory_hashes)); \ No newline at end of file diff --git a/ipfs-add.sh b/ipfs-add.sh old mode 100644 new mode 100755 index 99aa760..d8590d6 --- a/ipfs-add.sh +++ b/ipfs-add.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash set -euET -o pipefail -ipfs cid base32 "$(ipfs add --ignore-rules-path result/www/.ipfsignore --pin=false --hidden -Qr "$(dirname "$0")/www")" +ipfs cid base32 "$(ipfs add --ignore-rules-path result/www/.ipfsignore --pin=false --hidden -Qr "$(dirname "$0")")" diff --git a/micro_ipfs.js b/micro_ipfs.js index b7c9695..2c2bb6d 100644 --- a/micro_ipfs.js +++ b/micro_ipfs.js @@ -336,16 +336,31 @@ var ipfs_self_hash = (function() { var expected_vanity_attempt = 32*32*32; var max_vanity_attempt = expected_vanity_attempt*10; - function find_vanity_node(old_root, vanity_text, vanity_attempt, ipfs_directory_hashes) { + function find_vanity_node(vanity_text, vanity_attempt, ipfs_directory_hashes) { + if ((! (typeof vanity_text == 'string' || vanity_text instanceof String)) || vanity_text.length != 3) { + throw 'find_vanity_node(vanity_text, ...) : expected a string of length 3'; + } + var offset = 1; + switch (vanity_text[2]) { + case '4': + case 'a': + case 'e': + case 'i': + case 'm': + case 'q': + case 'u': + case 'y': + offset = 0; + } while (true) { if (vanity_attempt > max_vanity_attempt) { // give up: - return null; + throw 'Failed to brute-force a number that generates the desired vanity text.'; } else { var root = get_root_with_vanity(vanity_attempt, ipfs_directory_hashes); - if (root.hash[root.hash.length-1] == vanity_text[2] && root.hash[root.hash.length-2] == vanity_text[1]) { + if (root.hash[root.hash.length-1-offset] == vanity_text[2] && root.hash[root.hash.length-2-offset] == vanity_text[1]) { console.error(vanity_attempt + ' (' + Math.floor(100*vanity_attempt/expected_vanity_attempt) + '%)'); - if (root.hash[root.hash.length-3] == vanity_text[0]) { + if (root.hash[root.hash.length-3-offset] == vanity_text[0]) { return vanity_attempt; } } @@ -354,25 +369,44 @@ var ipfs_self_hash = (function() { } }; - function find_vanity_browser(old_root, vanity_text, vanity_attempt, callback, ipfs_directory_hashes) { + function find_vanity_browser_(offset, old_root, vanity_text, vanity_attempt, callback, ipfs_directory_hashes) { var root = get_root_with_vanity(vanity_attempt, ipfs_directory_hashes); if (vanity_attempt > max_vanity_attempt) { // give up: root = get_root_with_vanity(ipfs_directory_hashes.vanity_number, ipfs_directory_hashes) callback(root, 'timeout', false); } else { - if (root.hash[root.hash.length-1] == vanity_text[2]) { + if (root.hash[root.hash.length-1-offset] == vanity_text[2]) { callback(old_root, '… ' + vanity_attempt + ' (' + Math.floor(100*vanity_attempt/expected_vanity_attempt) + '%)', false); - if (root.hash[root.hash.length-2] == vanity_text[1] && root.hash[root.hash.length-3] == vanity_text[0]) { + if (root.hash[root.hash.length-2-offset] == vanity_text[1] && root.hash[root.hash.length-3-offset] == vanity_text[0]) { callback(root, vanity_attempt, true); } else { - window.setTimeout(function() { find_vanity_browser(old_root, vanity_text, vanity_attempt + 1, callback, ipfs_directory_hashes); }, 0); + window.setTimeout(function() { find_vanity_browser_(offset, old_root, vanity_text, vanity_attempt + 1, callback, ipfs_directory_hashes); }, 0); } } else { - window.setTimeout(function() { find_vanity_browser(old_root, vanity_text, vanity_attempt + 1, callback, ipfs_directory_hashes); }, 0); + window.setTimeout(function() { find_vanity_browser_(offset, old_root, vanity_text, vanity_attempt + 1, callback, ipfs_directory_hashes); }, 0); } } }; + + var find_vanity_browser = function(old_root, vanity_text, vanity_attempt, callback, ipfs_directory_hashes) { + if ((! (typeof vanity_text == 'string' || vanity_text instanceof String)) || vanity_text.length != 3) { + throw 'find_vanity_node(vanity_text, ...) : expected a string of length 3'; + } + var offset = 1; + switch (vanity_text[2]) { + case '4': + case 'a': + case 'e': + case 'i': + case 'm': + case 'q': + case 'u': + case 'y': + offset = 0; + } + return find_vanity_browser(offset, old_root, vanity_text, vanity_attempt, callback, ipfs_directory_hashes) + }; var debug = function(show_link) { var root = get_root_with_vanity(ipfs_directory_hashes.vanity_number, ipfs_directory_hashes); diff --git a/update_directory_hashes.sh b/update_directory_hashes.sh index 7832972..4bd27cd 100755 --- a/update_directory_hashes.sh +++ b/update_directory_hashes.sh @@ -2,14 +2,14 @@ set -euET -o pipefail -vanity_text="${1:-xyz}" -directory="${2:-.}" +directory="${1:-.}" +vanity_text="${2:-}" temp_file="$(mktemp)" hexdump="$(mktemp)" if test -z "$vanity_text" -o "$vanity_text" = "-h" -o "$vanity_text" = "--help"; then - echo 'Usage: ./update-hashes.sh vanity-text [path/to/directory]' + echo 'Usage: ./update-hashes.sh [path/to/directory] [vanity-text]' echo 'The given directory should contain a file named meta.js, which will be overwritten.' echo 'The vanity text should be three letters, which will appear at the end of your website'\''s hash' exit 1 @@ -33,9 +33,11 @@ write_directory_hashes() { } write_directory_hashes "0" -vanity_number="$(node "$(dirname "$0")/find_vanity.js" "$directory/directory_hashes.js" "$vanity_text")" -printf 'Found vanity number: %s\n' $vanity_number >&2 -write_directory_hashes "$vanity_number" +if test -n "$vanity_text"; then + vanity_number="$(node "$(dirname "$0")/find_vanity.js" "$directory/directory_hashes.js" "$vanity_text")" + printf 'Found vanity number: %s\n' $vanity_number >&2 + write_directory_hashes "$vanity_number" +fi echo "The hash given by the page should be:" >&2 printf 'ipfs://%s\n' "$(ipfs cid base32 "$(ipfs add --ignore-rules-path "$directory/.ipfsignore" --hidden -Qr "$directory")")"