Is there any function or something like that by which I can create totally random strings or numbers?
You can create random numbers using qrand. If you need strings, you can convert the int to string. You could also check the QUuid class, which generates Universally Unique Identifiers. Those are not 'totally random', but they are unique.
int number;
int randomValue = qrand() % number;
returns a random number randomValue with 0 <= randomValue < number.
qrand() is declared in QtGlobal which is #included by many other Qt files.
int value;
QString aString = QString::number(value);
converts an integer to QString.
The following example generates alphabetic strings with capital letters from A to Z and length = len.
QString randString(int len)
{
QString str;
str.resize(len);
for (int s = 0; s < len ; ++s)
str[s] = QChar('A' + char(qrand() % ('Z' - 'A')));
return str;
}
This is not a very good method to generate random numbers within a given range. (In fact it's very very bad for most generators )
You are assuming that the low-order bits from the generator are uniformly distributed. This is not the case with most generators. In most generators the randomness occurs in the high order bits.
By using the remainder after divisions you are in effect throwing out the randomness.
You should scale using multiplication and division. Not using the modulo operator.
eg
my_numbe r= start_required + ( generator_output * range_required)/generator_maximum;
If generator_output is in [0, generator_maximum],
my_number will be in [start_required , start_required + range_required].
Use QUuid
#include <QUuid>
QString randomStr = QUuid::createUuid();
Works in Qt6
double value= QRandomGenerator::global()->bounded(0, 10);
Generate a double from 0 to 10
Here is the good answer using qrand(). The solution below uses QUuid, as already was suggested above, to generate random and unique ids (they are all hex numbers):
#include <QApplication>
#include <QDebug>
#include <QRegularExpression>
#include <QUuid>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// random hex string generator
for (int i = 0; i < 10; i++)
{
QString str = QUuid::createUuid().toString();
str.remove(QRegularExpression("{|}|-")); // if you want only hex numbers
qDebug() << str;
}
return a.exec();
}
Output
"479a494a852747fe90efe0dc0137d059"
"2cd7e3b404b54fad9154e46c527c368a"
"84e43735eacd4b8f8d733bf642476097"
"d7e824f920874f9d8b4264212f3bd385"
"40b1c6fa89254705801caefdab5edd96"
"b7067852cf9d45ca89dd7af6ffdcdd23"
"9a2e5e6b65c54bea8fb9e7e8e1676a1a"
"981fa826073947e68adc46ddf47e311c"
"129b0ec42aed47d78be4bfe279996990"
"818035b0e83f401d8a56f34122ba7990"
Related
I'm writing a program that accepts a string at the command prompt then converts each character of the string to corresponding 0-25 digit of the alphabet. Each digit is then used to encipher each character of another string the user enters after being prompted by the program. Each alphabetic character of the second string should match the order of the string of integers and the string of integers will wrap if the second string is longer. The goal of the program is the use the first string as a key to shift each character of a message (the second string).
Example (desired output):
User runs program and enters keyword: bad
User is prompted to enter string of alphabetical characters and punctuation only: Dr. Oz
Program converts keyword 'bad' into 1,0,3
Program enciphers message into Er. Ra
What I actually get is:
… T.B.S. …
I've tried many things but unfortunately I can't seem to figure out how to loop and wrap the key without looping the second message. If you run the program you will see my problem.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int shift(char key1);
int main(int argc, string argv[]) // user enter number at cmd prompt
{
if (argv[1] == '\0')
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
string key = argv[1]; // declare second arg as string
for (int i = 0, n = strlen(key); i < n; i++)
if (isdigit(key[i]) != 0 || argc != 2)
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
string text = get_string("plaintext: ");
printf("ciphertext: ");
int k;
char t;
for (int j = 0, o = strlen(text); j < o; j++)
{
t = text[j];
for (int i = 0, n = strlen(key); i < n; i++)
{
k = shift(key[i]);
if (isupper(t))
{
t += k;
if (t > 'Z')
{
t -= 26;
}
}
if (islower(t))
{
t += k;
if (t > 'z')
{
t -= 26;
}
}
printf("%c", t);
}
}
printf("\n");
}
int shift(char key1)
{
int k1 = key1;
if (islower(key1))
{
k1 %= 97;
}
if (isupper(key1))
{
k1 %= 65;
}
return k1;
}
I appreciate any help and suggestions but please keep in mind the solution should match the level of coding my program suggests. There may be many advanced ways to write this program but unfortunately we are still in the beginning of this course so showing new methods (which I will definitely try to understand) may go over my head.
Here's a modified version of your code, with changes based on my comments:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int shift(char key1);
int main(int argc, string argv[]) // user enter number at cmd prompt
{
if (argc != 2 || argv[1][0] == '\0')
{
fprintf(stderr, "Usage: ./vigenere keyword\n");
return 1;
}
string key = argv[1]; // declare second arg as string
for (int i = 0, n = strlen(key); i < n; i++)
{
if (!isalpha(key[i]))
{
fprintf(stderr, "Usage: ./vigenere keyword\n");
return 1;
}
}
string text = get_string("plain text: ");
printf("ciphertext: ");
int keylen = strlen(key);
int keyidx = 0;
for (int j = 0, o = strlen(text); j < o; j++)
{
int t = text[j];
if (isupper(t))
{
int k = shift(key[keyidx++ % keylen]);
t += k;
if (t > 'Z')
t -= 26;
}
else if (islower(t))
{
int k = shift(key[keyidx++ % keylen]);
t += k;
if (t > 'z')
t -= 26;
}
printf("%c", t);
}
printf("\n");
}
int shift(char key1)
{
if (islower(key1))
key1 -= 'a';
if (isupper(key1))
key1 -= 'A';
return key1;
}
The test for exactly two arguments and for a non-empty key are moved to the top. This is slightly different from what was suggested in the comments. The error messages are printed to standard error, not standard output. I'd probably replace the second 'usage' message with a more specific error — the key may only contain alphabetic characters or thereabouts. And the errors should include argv[0] as the program name rather than hard-coding the name. The key validation loop checks that the key is all alphabetic, rather than checking that they are not digits — there are more character classes than digits and letters. The code uses keyidx and keylen to track the length of the key and the position in the key. I use single-letter variable names, but usually only for loop indexes or simple pointers (usually pointers into strings); otherwise I use short semi-mnemonic names. There are two calls to shift() so that keyidx is only incremented when the input character is a letter. There are other ways that this could be coded.
One very important change not foretold in the comments is the change of type for t — from char to int. When it is a char, if you encrypt letter z with a letter late in the alphabet (e.g. y), the value 'z' + 24 overflows the (signed) char type prevalent on Intel machines, giving a negative value (most typically; formally, the behaviour is undefined). That leads to bogus outputs. Changing to int fixes that problem. Since the value of t is promoted to int anyway when passed to printf(), there is no harm done in the printing. I used the prompt plain text: with a space so that the input and output align on the page.
I decided not to use the extra local variable k1 in shift(). I also used subtraction instead of modulus as noted in the comments.
Given the program cc59 created from cc59.c, a sample run is:
$ cc59 bad
plain text: Dr. Oz
ciphertext: Er. Ra
$ cc59 zax
plain text: Er. Ra
ciphertext: Dr. Oz
$ cc59 ablewasiereisawelba
plain text: The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. The five boxing wizards jump quickly. How vexingly quick daft zebras jump. Bright vixens jump; dozy fowl quack.
ciphertext: Tip uqius fisef fkb uvmpt zzar lpi cehq dkk. Abck nj fkx oqxy jqne zskfn ljbykr bckj. Xpw fezp coxjyk sirivuw rmml ufjckmj. Lkw nmbzrody mytdk dbqx vetzej ncep. Xvthht wtbank rydt; lgzu jzxl qvlgg.
$ cc59 azpweaiswjwsiaewpza
plain text: Tip uqius fisef fkb uvmpt zzar lpi cehq dkk. Abck nj fkx oqxy jqne zskfn ljbykr bckj. Xpw fezp coxjyk sirivuw rmml ufjckmj. Lkw nmbzrody mytdk dbqx vetzej ncep. Xvthht wtbank rydt; lgzu jzxl qvlgg.
ciphertext: The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. The five boxing wizards jump quickly. How vexingly quick daft zebras jump. Bright vixens jump; dozy fowl quack.
$
The decrypting keys were derived by matching the 'encrypting' letters in row 1 with the decrypting letters in row 2 of the data:
abcdefghijklmnopqrstuvwxyz
azyxwvutsrqponmlkjihgfedcb
With encryption and decryption, the most basic acid test for the code is that the program can decrypt its own encrypted output given the correct decrypting key and the cipher text.
I'm using an android app to send values to control servos.
Code:
char inputData[4];
char buffer[3];
void loop()
{
if(Serial.available() > 3) {
for (int i = 0; i < 4; i++){
inputData[i] = Serial.read();
}
char buffer[4];
buffer[0] = inputData[1];
buffer[1] = inputData[2];
buffer[2] = inputData[3];
buffer[3] = '\0';
int angle = atoi(buffer);
Serial.write(angle);
}
}
Issue: I'm getting the values + A-F letters to address each servo - A10, A180, B30 etc. Now the trouble is turning this to an actual integer. As you can see I've declared a character array to store the integers in and as suggested in a post on the arduino forum, I added a \0 at the end of the array. Currently, the Atoi returns random characters, mostly squares and some random numbers. I've tried even assigning them to a string and then .toInt() but same issue there, mostly squares.
Any ideas?
Thanks!
Use print or println to see the number as text. write sends it as byte and Serial Monitor shows a symbol with that ASCII code.
I am trying to analyze some program that resemble the following using the value analysis:
int main(int argc, char **argv){
char *argv0 = argv[0];
char x = argv0[1];
char y = argv0[2];
return 0;
}
After normalization and analysis the program looks like:
int main(int argc, char **argv){
int __retres;
char *argv0;
char x;
char y;
/*# assert Value: mem_access: \valid_read(argv + 0); */
argv0 = *(argv + 0);
/*# assert Value: mem_access: \valid_read(argv0 + 1); */
x = *(argv0 + 1);
/*# assert Value: mem_access: \valid_read(argv0 + 2); */
y = *(argv0 + 2);
__retres = 0;
return __retres;
}
where the status of the first two assert is 'unknown' and the status of the third one is 'invalid'. Moreover the value analysis tells me that *(argv0 + 2) is an invalid location and flags all code after it as dead.
I'd like to understand why the last assert is invalid (and not the first two) and why *(argv0 + 2) is an invalid location.
I'm using Frama-c Silicon-20161101
Thanks to anol's comment I was able to find the relevant section in the user manual of Value Analysis (http://frama-c.com/download/frama-c-value-analysis.pdf).
Here is an extract:
5.2.4 Tweaking the automatic generation of initial values (p58)
(...)
For a variable of a pointer type, there is no way for the analyzer to guess whether the pointer
should be assumed to be pointing to a single element or to be pointing at the beginning of
an array — or indeed, in the middle of an array, which would mean that it is legal to take
negative offsets of this pointer.
By default, a pointer type is assumed to point at the beginning of an array of two elements.
This number can be changed with option
-context-width.
I'm trying to convert raw hex/binary data to different file types.
#include <QByteArray>
#include <QDebug>
int main(int argc, char *argv[])
{
QByteArray package;
package.append( QByteArray::fromHex("a1"));
// "a1" is what is written to the memory, not the string representation of "a1"
qDebug() << package.toHex(); // "a1"
qDebug() << package; // "�"
qDebug() << package.toInt(); // 0
}
Why is the int representation 0 and not 161?
toInt has totally different purpose. It parses string representation of integer. If you want integer representing the value of the first byte of the array, use package[0]. It has char type. I don't remember how qDebug() represents char type, but if you have any problems with it, just static_cast it to unsigned int.
QByteArray::toInt expects that QByteArray contains a string of characters (in ASCII probably), not the binary representation of the number.
If you want to convert binary representation to integer you can use reinterpret_cast:
int i = *reinterpret_cast<quint8*>(package.constData());
Or better use qFromBigEndian/qFromLittleEndian:
int i = qFromLittleEndian<quint8>((const uchar*)package.constData())
In both cases you must know exactly in what format the number is stored and use proper type and endianness.
How get int code of qchar in this table http://www.ascii-codes.com/cp866.html ?
Here is my code:
int getCp866Code(QChar c) {
if (!c.isSurrogate()) {
QString temp = c;
QTextCodec* cp866 = QTextCodec::codecForName("IBM 866");
QByteArray byteArray = cp866->fromUnicode(temp);
return (int) byteArray[0];
}
return -1;
}
getCp866Code('ж') // returns -90, not 166
The question is ill posed. QChar is a UTF-16 code unit (which also means it can be part of a surrogate pair). Your best shot would be
Check that it's not part of a surrogate pair (QChar::isSurrogate)
Build a QString consisting only of that char, then use QTextCodec to encode the string in CP866. Then extract the first byte of it.
Note that it's unspecified what you get if your code point is not encodeable in CP866.