diff --git a/Makefile b/Makefile index 4bcc22d5a091357fd3827accd146768e7011e02f..50bff0c49b896f02fc5e26a1de41fcc51f91b7b9 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,9 @@ build: g++ git-commit-hash-vanity.cc -lssl -lcrypto -lpthread -O3 -o git-commit-hash-vanity - g++ sha1-benchmark.cc -lssl -lcrypto -O3 -o sha1-benchmark -bench: build +bench: + g++ sha1-benchmark.cc -lssl -lcrypto -O3 -o sha1-benchmark time ./sha1-benchmark -run: build - ./git-commit-hash-vanity - diff --git a/README.md b/README.md index ba0fdc420288482e4ba53e39f12f9e54721ebde2..460e129dd236f40409b917faed8c2099fc7b6085 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ 1. Run `git commit` 2. Run `git cat-file commit HEAD` -3. Run `git reset HEAD~1 ; git add -A`. +3. Run `git reset HEAD~1 --soft`. 4. Modify the `catfile_text` and `commit_msg` in `main()` , also modify the hash condition `if(unlikely(*(uint16_t *)hashbuf == 0))`. Also search for `+0800` if you need to modify timezone. 5. Commit the result. (You should commit exactly the same changes) diff --git a/git-commit-hash-vanity.cc b/git-commit-hash-vanity.cc index 9f76686bae974995a8c58bec064354adbf0f8912..2c2a6e7ad11c71a707dafd8e487b91d13ba61028 100644 --- a/git-commit-hash-vanity.cc +++ b/git-commit-hash-vanity.cc @@ -6,7 +6,10 @@ #include <cassert> #include <cmath> #include <cstring> -using namespace std::literals; +#include <rlib/stdio.hpp> +#include <rlib/string.hpp> +#include <rlib/opt.hpp> +using namespace rlib::literals; #define assertm(exp, msg) assert(((void)msg, exp)) #define likely(x) __builtin_expect((x),1) @@ -15,9 +18,9 @@ using byteptr = unsigned char *; void dump( const unsigned char *p, unsigned int n ) { for ( unsigned int i = 0; i < n; i++ ) { - std::cout << std::hex << (unsigned int)(p[i]) << " "; + std::cerr << std::hex << (unsigned int)(p[i]) << " "; } - std::cout << std::endl; + std::cerr << std::endl; } @@ -81,32 +84,42 @@ void crack_thread(const std::string catfile_fmt, long timestamp_begin, long time // TODO: add more requirement for check-hash auto outputbuf = new std::string(commit_msg.size() + 128, 0); std::sprintf(outputbuf->data(), commit_msg.c_str(), payload_msg_buf.data()); - std::printf("Found answer: GIT_COMMITTER_DATE='%ld +0800' git commit -m '%s' --date '%ld +0800'\n", payload_ts_count_2, outputbuf->data(), payload_ts_count_1); + std::printf("GIT_COMMITTER_DATE='%ld +0800' git commit -m '%s' --date '%ld +0800'\n", payload_ts_count_2, outputbuf->data(), payload_ts_count_1); #ifdef DEBUG dump(hashbuf, 20); databuf[head_size-1] = '|'; - std::printf("DEBUG: DATABUF >>>%s<<<, body_size=%ld\n", databuf.data(), body_size); + std::fprintf(stderr, "DEBUG: DATABUF >>>%s<<<, body_size=%ld\n", databuf.data(), body_size); #endif exit(0); } } } // No need to cleanup payload_msg_buf, because it only grows larger. Next call would overwrite it. - if(payload_msg_count % 0x8000 == 0) - std::printf("Thread finished %ld operations\n", payload_msg_count * (timestamp_end - timestamp_begin)); + if(payload_msg_count % 0x100 == 0) + std::fprintf(stderr, "Thread finished %ld operations\n", payload_msg_count * (timestamp_end - timestamp_begin) * (timestamp_end - timestamp_begin)); } } -int main() { - auto commit_msg = "First working version %s"; +int main(int argc, char **argv) { + rlib::opt_parser args(argc, argv); + if(args.getBoolArg("--help", "-h")) { + rlib::printfln(std::cerr, "Usage: {} --msg 'Update doc %s' --tree ce75e3b2f81907d4481569d753b7351321553579 --parent 0000000acda3fd97f5880cf0834c9498e01e774e --author 'Recolic Keghart <root@recolic.net>' --timezone '+0800'", args.getSelf()); + return 1; + } + auto commit_msg = args.getValueArg("--msg", "-m"); + auto tree_hash = args.getValueArg("--tree", "-t"); + auto parent_hash = args.getValueArg("--parent", "-p"); + auto author = args.getValueArg("--author", "-a"); + auto timezone = args.getValueArg("--timezone", "-z", false, "+0800"); + if(commit_msg.find("%s") == std::string::npos) throw std::invalid_argument("commit_msg must contain exactly one '%s'. "); + auto catfile_text = -R"TXT(tree db31568810a3fb76a8c127014f883f254180cb6d -parent 3d58156772f3bfd5b1ab303b05dc8f8c1483e845 -author Recolic Keghart <root@recolic.net> %ld +0800 -committer Recolic Keghart <root@recolic.net> %ld +0800 +R"TXT(tree {} +parent {} +author {} %ld {} +committer {} %ld {} -)TXT"s + commit_msg + "\n"; - // This program may generate git commit within the following time range. +)TXT"_format(tree_hash, parent_hash, author, timezone, author, timezone) + commit_msg + "\n"; auto timestamp_center = std::chrono::duration_cast<std::chrono::seconds>( std::chrono::system_clock::now().time_since_epoch() ).count(); diff --git a/vgitcommit b/vgitcommit new file mode 100755 index 0000000000000000000000000000000000000000..46ff822daa5872f5173150dd0ae30c1eaad37177 --- /dev/null +++ b/vgitcommit @@ -0,0 +1,43 @@ +#!/bin/bash +# You run this script instead of git-commit-hash-vanitygen to generate a commit. +# + +_self_bin_name="$0" +function where_is_him () { + SOURCE="$1" + while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located + done + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + echo -n "$DIR" +} +function where_am_i () { + _my_path=`type -p ${_self_bin_name}` + [[ "$_my_path" = "" ]] && where_is_him "$_self_bin_name" || where_is_him "$_my_path" +} +vanity_bin="$(where_am_i)/git-commit-hash-vanity" + +###################################################### +# script starts here + +[[ $1 = "" ]] && echo "Usage: $0 'Your Commit Message %s'" && exit 1 + +git commit -m '__tmp_commit_by_git-commit-hash-vanitygen' && + treehash=`git cat-file commit HEAD | head -n1 | cut -d ' ' -f 2` && + git reset HEAD~1 --soft || + exit $? + +parhash=`git rev-parse HEAD` && + author="$(git config user.name) <$(git config user.email)>" && + timezone=`date +%z` || + exit $? + +result_cmd=`"$vanity_bin" --msg "$1" --tree "$treehash" --parent "$parhash" --author "$author" --timezone "$timezone"` && + echo "Executing command: $result_cmd" && + eval "$result_cmd" || + exit $? + + +