#include <iostream>
#include <string>
#include <stdlib.h>
#include <cstdint>
#include <algorithm>
//this is not URI_Encode.
//this is like a URI_encode.not same.
std::string ItoA(std::int64_t N, const std::string& Ch) {
std::string R;
bool F = N >= 0 ? true : false;
while (N != 0) {
R += Ch[N % Ch.size()];
N /= Ch.size();//radix divide
}
if (!F) R += '-';
std::reverse(R.begin(), R.end());
return R;
}
std::intmax_t AtoI(const std::string& S, const std::string& Ch) {
std::uintmax_t R=0;
bool F = S[0] != '-'? true : false;
for(auto &o:S){
if (o == '-')continue;
auto it = std::find(Ch.begin(), Ch.end(),o);
R *= Ch.size();//radix multiple.
R += std::distance(Ch.begin(), it);
}
if (!F)R *= -1;
return R;
}
std::string ReversibleHash_Encode(const std::string& S,std::string C) {
std::string R;
for (auto& o : S) {
R += '%';
R += ItoA(static_cast<std::uint8_t>(o), C);
}
return R;
}
std::string ReversibleHash_Decode(const std::string& S,std::string C) {
std::string R;
std::string V;
bool F = true;
for (auto& o : S) {
std::uint8_t N = o;
if (o != '%') {
F = false;
V += o;
}
else {
if (F)continue;
R += AtoI(V.data(),C);
V.clear();
}
}
if (V.size())R += AtoI(V.data(), C);
return R;
}
int main() {
{
std::string R;
std::string S;
S = "ウィキペディア";
R = ReversibleHash_Encode(S, "0123456789");
std::cout << R << std::endl;
R = ReversibleHash_Decode(R, "0123456789");
std::cout << R << std::endl;
}
{
//dictionary Crypt.
std::string R;
std::string S;
std::string Ch = "abcdefghijklnmopqrstuvwxyz0123456789";
S = "ウィキペディア";
R = ReversibleHash_Encode(S, Ch);
std::cout << R << std::endl;
R = ReversibleHash_Decode(R, Ch);
std::cout << R << std::endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxjc3RkaW50PgojaW5jbHVkZSA8YWxnb3JpdGhtPgoKLy90aGlzIGlzIG5vdCBVUklfRW5jb2RlLgovL3RoaXMgaXMgbGlrZSBhIFVSSV9lbmNvZGUubm90IHNhbWUuCgpzdGQ6OnN0cmluZyBJdG9BKHN0ZDo6aW50NjRfdCBOLCBjb25zdCBzdGQ6OnN0cmluZyYgQ2gpIHsKCXN0ZDo6c3RyaW5nIFI7Cglib29sIEYgPSBOID49IDAgPyB0cnVlIDogZmFsc2U7Cgl3aGlsZSAoTiAhPSAwKSB7CgkJUiArPSBDaFtOICUgQ2guc2l6ZSgpXTsKCQlOIC89IENoLnNpemUoKTsvL3JhZGl4IGRpdmlkZQoJfQoJaWYgKCFGKSBSICs9ICctJzsKCglzdGQ6OnJldmVyc2UoUi5iZWdpbigpLCBSLmVuZCgpKTsKCglyZXR1cm4gUjsKCgp9CnN0ZDo6aW50bWF4X3QgQXRvSShjb25zdCBzdGQ6OnN0cmluZyYgUywgY29uc3Qgc3RkOjpzdHJpbmcmIENoKSB7CglzdGQ6OnVpbnRtYXhfdCBSPTA7Cglib29sIEYgPSBTWzBdICE9ICctJz8gdHJ1ZSA6IGZhbHNlOwoJZm9yKGF1dG8gJm86Uyl7CgkJaWYgKG8gPT0gJy0nKWNvbnRpbnVlOwoJCWF1dG8gaXQgPSBzdGQ6OmZpbmQoQ2guYmVnaW4oKSwgQ2guZW5kKCksbyk7CgkJUiAqPSBDaC5zaXplKCk7Ly9yYWRpeCBtdWx0aXBsZS4KCQlSICs9IHN0ZDo6ZGlzdGFuY2UoQ2guYmVnaW4oKSwgaXQpOwoJfQoJaWYgKCFGKVIgKj0gLTE7CgoJcmV0dXJuIFI7CgoKfQoKc3RkOjpzdHJpbmcgUmV2ZXJzaWJsZUhhc2hfRW5jb2RlKGNvbnN0IHN0ZDo6c3RyaW5nJiBTLHN0ZDo6c3RyaW5nIEMpIHsKCXN0ZDo6c3RyaW5nIFI7Cglmb3IgKGF1dG8mIG8gOiBTKSB7CgkJUiArPSAnJSc7CgkJUiArPSBJdG9BKHN0YXRpY19jYXN0PHN0ZDo6dWludDhfdD4obyksIEMpOwoJfQoJcmV0dXJuIFI7Cn0Kc3RkOjpzdHJpbmcgUmV2ZXJzaWJsZUhhc2hfRGVjb2RlKGNvbnN0IHN0ZDo6c3RyaW5nJiBTLHN0ZDo6c3RyaW5nIEMpIHsKCXN0ZDo6c3RyaW5nIFI7CglzdGQ6OnN0cmluZyBWOwoJYm9vbCBGID0gdHJ1ZTsKCWZvciAoYXV0byYgbyA6IFMpIHsKCQlzdGQ6OnVpbnQ4X3QgTiA9IG87CgkJaWYgKG8gIT0gJyUnKSB7CgkJCUYgPSBmYWxzZTsKCQkJViArPSBvOwoJCX0KCQllbHNlIHsKCQkJaWYgKEYpY29udGludWU7CgkJCVIgKz0gQXRvSShWLmRhdGEoKSxDKTsKCQkJVi5jbGVhcigpOwoJCX0KCX0KCWlmIChWLnNpemUoKSlSICs9IEF0b0koVi5kYXRhKCksIEMpOwoJcmV0dXJuIFI7Cn0KaW50IG1haW4oKSB7Cgl7CgkJc3RkOjpzdHJpbmcgUjsKCQlzdGQ6OnN0cmluZyBTOwoKCQlTID0gIuOCpuOCo+OCreODmuODh+OCo+OCoiI7CgoJCVIgPSBSZXZlcnNpYmxlSGFzaF9FbmNvZGUoUywgIjAxMjM0NTY3ODkiKTsKCgkJc3RkOjpjb3V0IDw8IFIgPDwgc3RkOjplbmRsOwoKCQlSID0gUmV2ZXJzaWJsZUhhc2hfRGVjb2RlKFIsICIwMTIzNDU2Nzg5Iik7CgoJCXN0ZDo6Y291dCA8PCBSIDw8IHN0ZDo6ZW5kbDsKCX0KCXsKCQkvL2RpY3Rpb25hcnkgQ3J5cHQuCgkJc3RkOjpzdHJpbmcgUjsKCQlzdGQ6OnN0cmluZyBTOwoJCXN0ZDo6c3RyaW5nIENoID0gImFiY2RlZmdoaWprbG5tb3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSI7CgkJUyA9ICLjgqbjgqPjgq3jg5rjg4fjgqPjgqIiOwoKCQlSID0gUmV2ZXJzaWJsZUhhc2hfRW5jb2RlKFMsIENoKTsKCgkJc3RkOjpjb3V0IDw8IFIgPDwgc3RkOjplbmRsOwoKCQlSID0gUmV2ZXJzaWJsZUhhc2hfRGVjb2RlKFIsIENoKTsKCgkJc3RkOjpjb3V0IDw8IFIgPDwgc3RkOjplbmRsOwoJfQoJcmV0dXJuIDA7Cn0=