我如何异或wchar_t输入,将其写入文件,并在C中读回?

wydwbb8l  于 2023-06-05  发布在  其他
关注(0)|答案(1)|浏览(139)

我在处理unicode字符串时遇到问题,wchar_t类型。
在我的程序中,我得到的输入是wchar_t,我应该对它进行异或,然后将其写入文件,读回并将其打印到命令行。
这是我的密码

const unsigned int XORKey = 0xff;


size_t XORit(const wchar_t* value, wchar_t* xorred)
{
    size_t length = wcslen(value);
    for (int i = 0; i < length; i++)
        xorred[i] = ((char)(value[i] ^ XORKey));

    return length;
}

int main()
{
    setlocale(LC_ALL, "en_US.UTF-8");
    // XOR it
    wchar_t sample[] = { L"TEST1自己人" };
    int samplelen = wcslen(sample);
    printf("%ls", sample);
    printf("\n");

    printf("Plain:\n\t");
    for (int i = 0; i < samplelen; i++)
    {
        printf("%02X ", sample[i]);
    }
    printf("\n");


    wchar_t* xorred = (wchar_t*)malloc(samplelen);
    if (xorred == NULL) return -1;
    memset(xorred, 0, samplelen);
    XORit(sample, xorred);
    printf("XOR'ed\n\t");
    for (int i = 0; i < samplelen; i++)
    {
        printf("%02X ", xorred[i]);
    }
    printf("\n");

    // Write to file
    FILE* fpW = _wfopen(L"logon.bin", L"wb");
    fwrite(xorred, sizeof(wchar_t), samplelen, fpW);
    fclose(fpW);

    // Read from file
    FILE* fpR = fopen("logon.bin", "rb");
    fseek(fpR, 0, SEEK_END);
    int filesize = ftell(fpR);
    wchar_t* unxorred = (wchar_t*)malloc(filesize + sizeof(wchar_t));
    if (unxorred == NULL) return -1;

    rewind(fpR);

    fread(unxorred, sizeof(wchar_t), filesize, fpW);
    fclose(fpW);

    printf("Reading\n\t");
    for (int i = 0; i < samplelen; i++)
    {
        printf("%02X ", unxorred[i]);
    }
    printf("\n");

    printf("Un-XOR'ed\n\t");
    for (int i = 0; i < samplelen; i++)
    {
        printf("%02X ", unxorred[i] ^ XORKey);
    }
    printf("\n");
    printf("%ls", unxorred);

    return 0;
}

我从文件中阅读回的值与我写的不匹配!:(我是C编程新手,我尽了最大的努力来做好这件事,请原谅我在理解和实现这个问题时犯的任何错误。
先谢谢你了
我根据注解修改了代码

const unsigned int XORKey = 0xff;


size_t XORit(const wchar_t* value, wchar_t* xorred)
{
    size_t length = wcslen(value);
    for (int i = 0; i < length; i++)
        xorred[i] = (value[i] ^ XORKey);

    return length;
}

int main()
{
    setlocale(LC_ALL, "en_US.UTF-8");
    // XOR it
    wchar_t sample[] = { L"Test1自己人自己人A" };
    int samplelen = wcslen(sample);
    printf("%ls", sample);
    printf("\n");

    printf("Plain:\n\t");
    for (int i = 0; i < samplelen; i++)
    {
        printf("%0*X ", (int)sizeof(wchar_t), (unsigned int)sample[i]);
    }
    printf("\n");


    wchar_t* xorred = (wchar_t*)malloc(samplelen);
    if (xorred == NULL) return -1;
    memset(xorred, 0, samplelen);
    XORit(sample, xorred);
    printf("XOR'ed\n\t");
    for (int i = 0; i < samplelen; i++)
    {
        printf("%0*X ", (int)sizeof(wchar_t), (unsigned int)xorred[i]);
    }
    printf("\n");

    // Write to file
    FILE* fpW = _wfopen(L"logon.bin", L"wb");
    fwrite(xorred, sizeof(wchar_t), samplelen, fpW);
    fclose(fpW);

    // Read from file
    FILE* fpR = fopen("logon.bin", "rb");
    fseek(fpR, 0, SEEK_END);
    int filesize = ftell(fpR);
    int whattoread = (filesize / sizeof(wchar_t));
    wchar_t* ReadXOR = (wchar_t*)malloc(filesize + 1);
    if (ReadXOR == NULL) return -1;
    memset(ReadXOR, 0, filesize + 1);

    rewind(fpR);

    fread(ReadXOR, sizeof(wchar_t), whattoread, fpR);
    fclose(fpW);

    printf("Reading\n\t");
    for (int i = 0; i < samplelen; i++)
    {
        printf("%0*X ", (int)sizeof(wchar_t), (unsigned int)ReadXOR[i]);
    }
    printf("\n");

    wchar_t* unxorred = (wchar_t*)malloc(whattoread);
    if (unxorred == NULL) return -1;
    memset(unxorred, 0, whattoread);
    printf("Un-XOR'ed\n\t");
    for (int i = 0; i < whattoread; i++)
    {
        unxorred[i] = ReadXOR[i] ^ 0xff;
        printf("%0*X ", (int)sizeof(wchar_t), (unsigned int)unxorred[i]);
    }
    printf("\n");
    printf("%ls\n", unxorred);
    printf("%ls\n", sample);
    

    return 0;

输出如下所示,

Test1自己人自己人A
Plain:
        54 65 73 74 31 81EA 5DF1 4EBA 81EA 5DF1 4EBA 41
XOR'ed
        AB 9A 8C 8B CE 8115 5D0E 4E45 8115 5D0E 4E45 BE
Reading
        AB 9A 8C 8B CE 8115 5D0E 4E45 8115 5D0E 4E45 BE
Un-XOR'ed
        54 65 73 74 31 81EA 5DF1 4EBA 81EA 5DF1 4EBA 41
Test1自己人自己人A粘蹊?言?萉?
Test1自己人自己人A

当我修改unicode字符串时,我在输出中得到了错误的文本!

kcwpcxri

kcwpcxri1#

这里...

printf("Un-XOR'ed\n\t");
    for (int i = 0; i < samplelen; i++)
    {
        printf("%02X ", unxorred[i] ^ XORKey);
    }
    printf("\n");

...你打印出解码的值 * 而不存储它们 *。
当你…

printf("%ls", unxorred);

...您正在打印从文件中读回的数据,* 而不是 * 与先前打印的代码序列相对应的解码字符串。
此外,

  • 这里
int filesize = ftell(fpR);
    wchar_t* unxorred = (wchar_t*)malloc(filesize);
    if (unxorred == NULL) return -1;

    rewind(fpR);

    fread(unxorred, sizeof(wchar_t), filesize, fpW);

...你试图从文件中读回sizeof(wchar_t) * filesize字节,这比它实际包含的或你分配的要多(除非sizeof(wchar_t)是1,这是可能的,但不太可能,无论如何不是你的情况)。

  • 您不为(宽)字符串结束符分配空间,也不向回读数据添加一个结束符,但如果它是宽字符串,则将其传递给printf() is。这是错误的。
  • 您打印宽字符串的字节的方法是有缺陷的。转换说明符X需要一个对应的unsigned int参数,wchar_t可能既不与unsigned int相同,也不通过默认参数升级为unsigned int。此外,由于wchar_t至少为16位宽,而02仅保证2个十六进制数字,因此可以获得可变长度输出。最好是,例如:
for (int i = 0; i < samplelen; i++) {
    printf("%0*X ", (int) sizeof(wchar_t), (unsigned int) xorred[i]);
}

width的*表示最小字段宽度将作为int类型的参数传递。强制转换将参数与格式所需的类型相匹配。

相关问题