| #include <cmath> | |
| #include <fstream> | |
| #include <iostream> | |
| #include <sys/stat.h> | |
| #include <vector> | |
| int32_t ascii_to_int(std::string c) { | |
| int32_t rv; | |
| for (size_t i=0; i<c.size(); ++i) { | |
| rv <<= 8; | |
| rv |= (int)c[i] & 0xFF; | |
| } | |
| return rv; | |
| } | |
| int32_t base85_to_int(std::string c) { | |
| int32_t rv = 0; | |
| for (int i=c.size()-1; i>=0; --i) { | |
| int x = ((int) c[i]) - 33; | |
| rv += x * (pow(85, (c.size()-i-1))); | |
| } | |
| return rv; | |
| } | |
| std::string int_to_base85(int32_t x) { | |
| std::string rv; | |
| int32_t rem = 0; | |
| for (int i=4; i>=0; --i) { | |
| rem = x % 85; | |
| rv.insert(rv.begin(), (char) (rem + 33)); | |
| x = (x-rem) / 85; | |
| } | |
| return rv; | |
| } | |
| std::string int_to_ascii(int32_t x) { | |
| std::string rv; | |
| int32_t rem = 0; | |
| for (int i=4; i>0; --i) { | |
| rem = x & 127; | |
| rv.insert(rv.begin(), (char) rem); | |
| x >>= 8; | |
| } | |
| return rv; | |
| } | |
| int code(std::ifstream & in, int in_len, char pad_char, int32_t (*f1)(std::string), std::string (*f2)(int32_t)) | |
| { | |
| std::string cx(" "); | |
| int i = 0; | |
| int j = 0; | |
| int rv = 0; | |
| std::string whole; | |
| while (!in.eof()) { | |
| j = 0; | |
| for (i=0; i<in_len && !in.eof(); ++i) in.get(cx[i]); | |
| if (in.eof() && i < in_len) { | |
| for (j=i; j<in_len+1; ++j) cx[j-1] = pad_char; | |
| j -= i; | |
| } | |
| i = 0; | |
| whole.append(f2(f1(cx))); | |
| } | |
| if (j>0) whole.erase(whole.size()-j); | |
| std::cout << whole << std::endl; | |
| return rv; | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| if (argc < 3) { | |
| std::cout << "Usage: " << argv[0] << "OPTION FILENAME" << std::endl; | |
| std::cout << "\t-e\tencode to ASCII85" << std::endl; | |
| std::cout << "\t-d\tdecode from ASCII85" << std::endl; | |
| return 0; | |
| } | |
| std::string opt = argv[1]; | |
| if (opt != "-e" && opt != "-d") { | |
| std::cout << "Wrong option: " << opt << std::endl; | |
| return 0; | |
| } | |
| bool encodingMode = (opt == "-e"); | |
| char * filename; | |
| filename = argv[2]; | |
| struct stat buf; | |
| stat(filename, &buf); | |
| std::cerr << "Reading " << filename << ", size: " << buf.st_size << std::endl; | |
| std::ifstream in; | |
| in.open(filename, std::ios::in | std::ios::binary); | |
| if (!in || !in.is_open()) { | |
| std::cerr << "Can't open input file " << filename << std::endl; | |
| return 1; | |
| } | |
| int rv = 1; | |
| if (encodingMode) { | |
| rv = code(in, 4, '\0', ascii_to_int, int_to_base85); | |
| } else { | |
| rv = code(in, 5, 'u', base85_to_int, int_to_ascii); | |
| } | |
| if (in.is_open()) in.close(); | |
| return rv; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment