与转换为整数,二进制文件,它的ASCII表示

问题描述 投票:0回答:2

我有一个二进制文件,包括代表的ASCII文件整数。例如包含hello一个文件具有(使用XXD)的值

0000000: 4800 0000 6500 0000 6c00 0000 6c00 0000  H...e...l...l...
0000010: 6f00 0000 0000 0000                      o.......

我怎样才能读取该文件,并将其转换为ASCII字符串Hello

编辑的例子,显示的正是我做什么我得到。只需编译并运行它。将一个名为“test.txt的该PWD这就是里面的明文消息,结果是2个文件test.enc和test.dec。我知道它是不安全的所有,但我无论如何要创建此。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define ACCURACY 5
#define SINGLE_MAX 100000
#define EXPONENT_MAX 10000
#define BUF_SIZE 1024
#define DEBUG 0

int modpow(long long a, long long b, int c) {
    int res = 1;
    while(b > 0) {
        /* Need long multiplication else this will overflow... */
        if(b & 1) {
            res = (res * a) % c;
        }
        b = b >> 1;
        a = (a * a) % c; /* Same deal here */
    }
    return res;
}

int jacobi(int a, int n) {
    int twos, temp;
    int mult = 1;
    while(a > 1 && a != n) {
        a = a % n;
        if(a <= 1 || a == n) break;
        twos = 0;
        while(a % 2 == 0 && ++twos) a /= 2; /* Factor out multiples of 2 */
        if(twos > 0 && twos % 2 == 1) mult *= (n % 8 == 1 || n % 8 == 7) * 2 - 1;
        if(a <= 1 || a == n) break;
        if(n % 4 != 1 && a % 4 != 1) mult *= -1; /* Coefficient for flipping */
        temp = a;
        a = n;
        n = temp;
    }
    if(a == 0) return 0;
    else if(a == 1) return mult;
    else return 0; /* a == n => gcd(a, n) != 1 */
}

int solovayPrime(int a, int n) {
    int x = jacobi(a, n);
    if(x == -1) x = n - 1;
    return x != 0 && modpow(a, (n - 1)/2, n) == x;
}

int probablePrime(int n, int k) {
    if(n == 2) return 1;
    else if(n % 2 == 0 || n == 1) return 0;
    while(k-- > 0) {
        if(!solovayPrime(rand() % (n - 2) + 2, n)) return 0;
    }
    return 1;
}

int randPrime(int n) {
    int prime = rand() % n;
    n += n % 2; /* n needs to be even so modulo wrapping preserves oddness */
    prime += 1 - prime % 2;
    while(1) {
        if(probablePrime(prime, ACCURACY)) return prime;
        prime = (prime + 2) % n;
    }
}

int gcd(int a, int b) {
    int temp;
    while(b != 0) {
        temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

int randExponent(int phi, int n) {
    int e = rand() % n;
    while(1) {
        if(gcd(e, phi) == 1) return e;
        e = (e + 1) % n;
        if(e <= 2) e = 3;
    }
}

int inverse(int n, int modulus) {
    int a = n, b = modulus;
    int x = 0, y = 1, x0 = 1, y0 = 0, q, temp;
    while(b != 0) {
        q = a / b;
        temp = a % b;
        a = b;
        b = temp;
        temp = x; x = x0 - q * x; x0 = temp;
        temp = y; y = y0 - q * y; y0 = temp;
    }
    if(x0 < 0) x0 += modulus;
    return x0;
}

int readFile(FILE* fd, char** buffer, int bytes) {
    int len = 0, cap = BUF_SIZE, r;
    char buf[BUF_SIZE];
    *buffer = malloc(BUF_SIZE * sizeof(char));
    while((r = fread(buf, sizeof(char), BUF_SIZE, fd)) > 0) {
        if(len + r >= cap) {
            cap *= 2;
            *buffer = realloc(*buffer, cap);
        }
        memcpy(&(*buffer)[len], buf, r);
        len += r;
    }
    /* Pad the last block with zeros to signal end of cryptogram. An additional block is added if there is no room */
    if(len + bytes - len % bytes > cap) *buffer = realloc(*buffer, len + bytes - len % bytes);
    do {
        (*buffer)[len] = '\0';
        len++;
    }
    while(len % bytes != 0);
    return len;
}

int encode(int m, int e, int n) {
    return modpow(m, e, n);
}

int decode(int c, int d, int n) {
    return modpow(c, d, n);
}

int* encodeMessage(int len, int bytes, char* message, int exponent, int modulus) {
    int *encoded = malloc((len/bytes) * sizeof(int));
    int x, i, j;
    for(i = 0; i < len; i += bytes) {
        x = 0;
        for(j = 0; j < bytes; j++) x += message[i + j] * (1 << (7 * j));
        encoded[i/bytes] = encode(x, exponent, modulus);
        if(DEBUG) printf("%d ", encoded[i/bytes]);
    }
    return encoded;
}

int* decodeMessage(int len, int bytes, int* cryptogram, int exponent, int modulus) {
    int *decoded = malloc(len * bytes * sizeof(int));
    int x, i, j;
    for(i = 0; i < len; i++) {
        x = decode(cryptogram[i], exponent, modulus);
        for(j = 0; j < bytes; j++) {
            decoded[i*bytes + j] = (x >> (7 * j)) % 128;
            if(DEBUG) if(decoded[i*bytes + j] != '\0') printf("%c", decoded[i*bytes + j]);
        }
    }
    return decoded;
}       

int main(void) {

    int p, q, n, phi, e, d;
    int len;
    int bytes = 1;
    int *encoded, *decoded;
    char *buffer;
    FILE *f;
    srand(time(NULL));

    while(1) {

        p = randPrime(SINGLE_MAX);              
        q = randPrime(SINGLE_MAX);      
        n = p * q;
        if(n < 128) {
            printf("Modulus is less than 128, trying again\n");
        } else {
            break;
        }

    }   

    phi = (p - 1) * (q - 1);
    e = randExponent(phi, EXPONENT_MAX);    
    d = inverse(e, phi);

    // read the file
    f = fopen("test.txt", "r");
    if(f == NULL) return EXIT_FAILURE;
    len = readFile(f, &buffer, bytes); // len will be a multiple of bytes, to send whole chunks 
    fclose(f);

    if(DEBUG) printf("Encoded: ");
    encoded = encodeMessage(len, bytes, buffer, e, n);

    // save the encoded binary! to file
    FILE *encodedFile;
    encodedFile = fopen("tmp.enc", "wb");
    fwrite(encoded, sizeof(int), len, encodedFile);
    fclose(encodedFile);

    // read the encodedFile binary! overwrite encoded!!!
    FILE *newEncodedFile;
    newEncodedFile = fopen("tmp.enc", "rb");
    fread(encoded, sizeof(int), len, newEncodedFile);
    fclose(newEncodedFile);

    if(DEBUG) printf("\nDecoded: ");
    decoded = decodeMessage(len/bytes, bytes, encoded, d, n);

    // save the decoded binary! to file
    FILE *decodedFile;
    decodedFile = fopen("tmp.dec", "wb");
    fwrite(decoded, sizeof(int), len/bytes, decodedFile);
    fclose(decodedFile);

    free(encoded);
    free(decoded);
    free(buffer);

    return EXIT_SUCCESS;
}
c ascii
2个回答
1
投票

字符是根据一些任意的规则显示只是整数。因为规则是任意有无限的可能性。那些无限可能性的存在多个标准(EBDIC,ASCII的“扩展ASCII”许多变化,统一等),因为他们都只是为整数,有许多方法来对其进行编码(“原样”,UTF-8,UTF -16LE,UTF-16BE,..)。

要的东西转换到任何东西,你需要解码原始编码(如果有的话),所产生的字符转换为新的字符集(可能通过。查找表),然后重新编码目标编码的字符(如果有的话) 。

你显示的数据看起来像“的Unicode与UTF-32LE编码”。为了将其转换为“ASCII与AS-被编码”(以便携的方式),你需要通过解码原始编码(例如codepoint = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24))开始。然后,你需要生成的代码点(“人物”)转换成ASCII字符集。幸运的是,第一码点128以Unicode是相同的ASCII。不幸的是,几乎所有的Unicode中的其他代码点不能被转换为ASCII,所以你需要决定如何处理这(在一个ASCII字符'?'取代他们?生成一个“不能转换”错误信息和放弃?)。在任何情况下,它可能会看起来像if(codepoint < 128) { character = codepoint; } else {。最后,由于ASCII采用了“原样”编码你可以一巴掌生成的字节到内存(有没有参与过“再编码”的工作)。


0
投票

没有测试,但是这样的事情:

int utf32le2ascii(uint32_t *instr, size_t len, char *outstr, size_t outlen)
{
    size_t i, j = 0;
    for (i = 0; i < len; i++)
    {
        if (j >= outlen)
        {
            return -1;
        }

        if (instr[i] < 128)
        {
            outstr[j] = instr[i];
        }

        else
        {
            outstr[j] = '?'; 
        }

        j++;
    }
    if (j >= outlen)
    {
        return -1;
    }

    outstr[j] = '\0';
    return 0;
}

-1的的返回值表示故障; 0表示成功。

© www.soinside.com 2019 - 2024. All rights reserved.