C++程序错误地输出了消息。

huangapple go评论78阅读模式
英文:

The C++ program incorrectly outputs the message

问题

以下是翻译好的代码部分:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

// Constants declaration
const int MAX = 1000;
const int PRIME = 31;

// Function to calculate the power of a number modulo another number
int power(int x, unsigned int y, int p)
{
    int res = 1;
    x = x % p;

    while (y > 0) {
        if (y & 1)
            res = (res * x) % p;

        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}

int main()
{
    string message;
    cout << "Enter the message to be encrypted: ";
    getline(cin, message);

    int n, k;
    cout << "Enter the number of keys (n): ";
    cin >> n;
    cout << "Enter the number of keys required for decryption (k): ";
    cin >> k;

    int secretKey = rand() % PRIME;
    vector<int> coefficients(k - 1);
    for (int i = 0; i < k - 1; i++) {
        coefficients[i] = rand() % PRIME;
    }

    vector<int> keys(n);
    for (int i = 1; i <= n; i++) {
        keys[i - 1] = power(PRIME, i, MAX);
    }

    vector<int> shares(n);
    for (int i = 0; i < n; i++) {
        int sum = secretKey;
        for (int j = 0; j < k - 1; j++) {
            sum += coefficients[j] * power(keys[i], j + 1, MAX);
        }
        shares[i] = sum;
    }

    vector<int> selectedKeys(k);
    cout << "Enter the keys to be used for decryption: ";
    for (int i = 0; i < k; i++) {
        cin >> selectedKeys[i];
        if (selectedKeys[i] < 1 || selectedKeys[i] > n) {
            cout << "Invalid key. Please try again: ";
            i--;
        }
    }
    sort(selectedKeys.begin(), selectedKeys.end());

    int secretMessage = 0;
    for (int i = 0; i < k; i++) {
        int num = shares[selectedKeys[i] - 1];
        int denom = 1;
        for (int j = 0; j < k; j++) {
            if (i != j) {
                num *= keys[selectedKeys[j] - 1];
                denom *= keys[selectedKeys[j] - 1] - keys[selectedKeys[i] - 1];
            }
        }
        secretMessage += num / denom;
    }

    string encryptedMessage = "";
    string decryptedMessage = "";
    for (int i = 0; i < message.length(); i++) {
        int val = message[i];
        int encryptedVal = val ^ secretKey;
        encryptedMessage += char(encryptedVal);
        int decryptedVal = encryptedVal ^ secretMessage;
        decryptedMessage += char(decryptedVal);
    }

    cout << "The secret key is: " << secretKey << endl;
    cout << "The shares are: ";
    for (int i = 0; i < n; i++) {
        cout << shares[i] << " ";
    }
    cout << endl;
    cout << "The decrypted message is: " << decryptedMessage << endl;
    cout << "The encrypted message is: " << encryptedMessage << endl;

    return 0;
}

示例输出:

Enter the message to be encrypted: Hello World
Enter the number of keys (n): 6
Enter the number of keys required for decryption (k): 3
Enter the keys to be used for decryption: 3 2 1
The secret key is: 10
The shares are: 10302 26362 24222 15882 11342 22602
The decrypted message is: ┤ЩРРУ▄лУОРШ
The encrypted message is: Boffe*]exfn
英文:

My program encrypts and decrypts the message according to Shamir's algorithm, one finally decrypted message does not converge with the input, they say that this problem may be related to encoding, however, I think that the problem is in the code and I cannot understand my mistake.

I tried to change the encryption type, instead of addition and subtraction, I did XOR, added array sorting, in case the problem is there, but it didn't help

#include &lt;iostream&gt;   
#include &lt;cstdlib&gt;   
#include &lt;ctime&gt;   
#include &lt;vector&gt;   
#include &lt;string&gt;   
#include &lt;algorithm&gt; // для функции sort 
using namespace std;
// Объявляем константы   
const int MAX = 1000;
const int PRIME = 31;
// Функция, вычисляющая степень числа по модулю   
int power(int x, unsigned int y, int p)
{
int res = 1; // Инициализируем результат   
x = x % p; // Берем остаток от деления x на p   
while (y &gt; 0) {
// Если степень нечетная, умножаем результат на x   
if (y &amp; 1)
res = (res * x) % p;
// Уменьшаем степень вдвое и удваиваем x   
y = y &gt;&gt; 1;
x = (x * x) % p;
}
return res;
}
int main()
{
string message; // Объявляем переменную для сообщения   
cout &lt;&lt; &quot;Enter the message to be encrypted: &quot;;
getline(cin, message); // Получаем сообщение от пользователя   
int n, k; // Объявляем переменные для количества ключей   
cout &lt;&lt; &quot;Enter the number of keys (n): &quot;;
cin &gt;&gt; n;
cout &lt;&lt; &quot;Enter the number of keys required for decryption (k): &quot;;
cin &gt;&gt; k;
// Генерируем случайный секретный ключ и коэффициенты   
int secretKey = rand() % PRIME;
vector&lt;int&gt; coefficients(k - 1);
for (int i = 0; i &lt; k - 1; i++) {
coefficients[i] = rand() % PRIME;
}
// Генерируем ключи   
vector&lt;int&gt; keys(n);
for (int i = 1; i &lt;= n; i++) {
keys[i - 1] = power(PRIME, i, MAX);
}
// Создаем части секретного сообщения   
vector&lt;int&gt; shares(n);
for (int i = 0; i &lt; n; i++) {
int sum = secretKey;
for (int j = 0; j &lt; k - 1; j++) {
sum += coefficients[j] * power(keys[i], j + 1, MAX);
}
shares[i] = sum;
}
// Пользователь выбирает ключи для расшифровки   
vector&lt;int&gt; selectedKeys(k);
cout &lt;&lt; &quot;Enter the keys to be used for decryption: &quot;;
for (int i = 0; i &lt; k; i++) {
cin &gt;&gt; selectedKeys[i];
if (selectedKeys[i] &lt; 1 || selectedKeys[i] &gt; n) { // проверка на правильность ввода ключей 
cout &lt;&lt; &quot;Invalid key. Please try again: &quot;;
i--;
}
}
sort(selectedKeys.begin(), selectedKeys.end()); // сортировка выбранных ключей 
// Восстанавливаем секретное сообщение   
int secretMessage = 0;
for (int i = 0; i &lt; k; i++) {
int num = shares[selectedKeys[i] - 1];
int denom = 1;
for (int j = 0; j &lt; k; j++) {
if (i != j) {
num *= keys[selectedKeys[j] - 1];
denom *= keys[selectedKeys[j] - 1] - keys[selectedKeys[i] - 1];
}
}
secretMessage += num / denom;
}
// Шифруем и расшифровываем сообщение   
string encryptedMessage = &quot;&quot;;
string decryptedMessage = &quot;&quot;;
for (int i = 0; i &lt; message.length(); i++) {
int val = message[i];
int encryptedVal = val ^ secretKey; // XOR-шифрование 
encryptedMessage += char(encryptedVal);
int decryptedVal = encryptedVal ^ secretMessage; // XOR-расшифрование 
decryptedMessage += char(decryptedVal);
}
// Выводим результаты на экран   
cout &lt;&lt; &quot;The secret key is: &quot; &lt;&lt; secretKey &lt;&lt; endl;
cout &lt;&lt; &quot;The shares are: &quot;;
for (int i = 0; i &lt; n; i++) {
cout &lt;&lt; shares[i] &lt;&lt; &quot; &quot;;
}
cout &lt;&lt; endl;
cout &lt;&lt; &quot;The decrypted message is: &quot; &lt;&lt; decryptedMessage &lt;&lt; endl;
cout &lt;&lt; &quot;The encrypted message is: &quot; &lt;&lt; encryptedMessage &lt;&lt; endl;
return 0;
}

Example output:

Enter the message to be encrypted: Hello World
Enter the number of keys (n): 6
Enter the number of keys required for decryption (k): 3
Enter the keys to be used for decryption: 3 2 1
The secret key is: 10
The shares are: 10302 26362 24222 15882 11342 22602
The decrypted message is: ┤ЩРРУ▄лУОРШ
The encrypted message is: Boffe*]exfn

答案1

得分: 1

除了调试,我建议添加不变性检查,例如在各个点上添加断言。此外,在开发过程中进行单元测试会有很大帮助。使用-fsanitize=undefined运行代码并检查是否存在未定义行为,如整数溢出等。

实际上,使用污染检查运行代码会显示错误:

x86-64 clang 16.0.0
x86-64 clang 16.0.0
-std=c++20 -fsanitize=integer -fsanitize=undefined
Program returned: 0
Program stdout
The secret key is: 10
The shares are: 3048 6378 6008 3938 3168 5698 
The decrypted message is: ����
The encrypted message is: ofge
Program stderr
/app/example.cpp:92:21: runtime error: signed integer overflow: 2929128 * 791 cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /app/example.cpp:92:21 in 

https://godbolt.org/z/b477shh1f

将以下行更改为:

num *= keys[selectedKeys[j] - 1]);

更改为:

num = (num * keys[selectedKeys[j] - 1]) % MAX;

可以修复这个问题。

英文:

Besides debugging I would suggest to add invariant checking, like assertions in various points. Also unit testing during development process helps a lot. Run your code with -fsanitize=undefined and check for any UBs, like integer overflows etc.

Actually running your code with sanitization shows error:

x86-64 clang 16.0.0
x86-64 clang 16.0.0
-std=c++20 -fsanitize=integer -fsanitize=undefined
Program returned: 0
Program stdout
The secret key is: 10
The shares are: 3048 6378 6008 3938 3168 5698 
The decrypted message is: ����
The encrypted message is: ofge
Program stderr
/app/example.cpp:92:21: runtime error: signed integer overflow: 2929128 * 791 cannot be represented in type &#39;int&#39;
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /app/example.cpp:92:21 in 

https://godbolt.org/z/b477shh1f

Changing line:

num *= keys[selectedKeys[j] - 1]);

to:

num = (num * keys[selectedKeys[j] - 1]) % MAX;

fixes it

huangapple
  • 本文由 发表于 2023年4月6日 22:41:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75950819.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定