2010-08-28 4 views
1

я получил задание генерировать случайные 80 ключи байт и я решил следующий strategesГенерация случайных ключей

в моем компьютере sizeof(char)=1 так я создал массив английских букв алфавита

char *p=" "; 
char a[0..26] and in cycle 


for (int i=0;i<=80;i++){ 
    *(p+i)+= a[(rand()+100) % 26]; 
} 

но это не работать он прекращает выполнение, пожалуйста, помогите извините, если мой код глупо, но я не могу думать в это время иначе благодаря код

#include <iostream> 
#include <string.h> 
#include <cstdlib> 
using namespace std; 
int main(){ 

    char *p=" "; 
    char a[]= { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; 
for (int i=0;i<=80;i++){ 
     *(p+i)+=(a[(rand()+100)%26]); 
    } 

    cout<<p<<endl; 


    return 0; 

} 
+0

Надеюсь, вы не генерируете эти ключи для криптографических приложений. rand() не подходит для таких целей. – andand

+3

Что-то, чего я не вижу в другом месте: '' '' '' const char [2] '. Что. Вы можете назначить его символу 'char *' - это случайность; вы по-прежнему не можете назначить новое значение '* p', даже если вы будете осторожны, чтобы оставаться в границах вашего массива. –

+0

Обратите внимание, что в C-стандарте 'sizeof (char)' равно 1. 'sizeof (char)' does ** not ** ссылается на количество октетов, которое занимает один объект 'char' в памяти. –

ответ

2

Попробуйте это:

#include <iostream> 
#include <string.h> 
#include <cstdlib> 
using namespace std; 
int main(){ 
    // ensure the target has enough memory for the key and a null terminator 
    char p[81]; 

    // this string will do as nicely as the character array 
    char a[] = "abcdefghijklmnopqrstuvwxyz"; 

    // no += here. I assign the random character directly to the target buffer 
    for (int i=0;i<=80;i++) 
     p[i] = a[rand()%26]; 

    // alternately, you can calculate a random English character with: 
    // p[i] = rand()%26 + 'a'; 
    // which removes the need for the a[] buffer at all 

    // don't forget to null-terminate 
    p[80] = '\0' 

    // output results 
    cout<<p<<endl; 
    return 0; 
} 
+1

Ваш код выглядит хорошо, но я бы рекомендовал добавить некоторое объяснение к вашим ответам в будущем (особенно для такого основного вопроса, как этот). –

+0

@ Давид: достаточно честный. Я не мог сказать больше, чем было сказано в других ответах, за исключением примечания о завершении нулевого уровня. Я сделаю все возможное, чтобы быть более наглядным в будущем. – kbrimington

+0

Что такое +100 для? Чтобы предотвратить несчастные случаи, может стоить сделать 'a' const. Кроме того, поскольку A является массивом, почему оператор модулей использует const. Измените размер массива. Таким образом, если массив расширен, вам не нужно обновлять алгоритм. –

1

Перед записью в цикле вам нужно выделить место для полного размера вашего массива символов p.


Update Кстати, rand() не очень случайным, если вы не семя его с уникальным значением первого использования srand.

1

Вы назначаете символы в своей переменной p, но вы не выделили память для назначения этих символов. Вероятно, вы хотите что-то вроде этого:

char p[81]; 

а затем идите оттуда.

3

Ну, обычно я бы сказал, что вы должны предоставить больше информации, чем «он прекращает выполнение», но несколько вещей, которые выскакивают на меня:

char *p=" "; 
    char a[]= { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; 
    for (int i=0;i<=80;i++){ 
     *(p+i)+=(a[(rand()+100)%26]); 
    } 

Ваш цикл записи значений в *p из индекса От 0 до 80 (81 общий элемент).

Первая итерация итерация:

*(p+0) = a[...]; 

будет работать, но второй один

*(p+1) = a[...]; 

должны терпеть неудачу, так как нет зарезервированной памяти по адресу * (р + 1). Это может быть отключено на единицу, если вы можете записать в пространство, зарезервированное для нулевого \0, которое добавлено в строковый литерал.

При объявлении * р как

char *p=" "; 

Вы выделяет только 1 байт. Итак, когда ваш цикл записывается в p [1], p [2] ... вы пытаетесь записать в нераспределенную память. Измените свою декларацию примерно на

char pArr[81]; 
char *p=pArr; 

и перейти оттуда.

+0

Синтаксис объявления верен. –

+0

@Venza спасибо. Я собирался выскочить из компилятора C. Легкие вопросы относятся к классу. –

+0

В вашей последней точке: p [0] и p [1] действительно указывают на реальную память. Тем не менее, это, скорее всего, только память. Исправление будет работать нормально. –

1

Я изменил свой код ... попробовать его.

#include <iostream> 
#include <string.h> 
#include <cstdlib> 
using namespace std; 
int main(){ 

    char *p= new char[81]; 
    char a[]= { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; 
for (int i=0;i<=80;i++){ 
     *(p+i)=(a[(rand()+100)%26]); 
    } 

    cout<<p<<endl; 


    return 0; 

} 

И какой выходной сигнал?

+2

Утечка памяти для стартеров. –

1

вопрос об этом коде:

Почему генерировать массив буквенных символов? Почему бы не получить случайный, модулировать на 26 и добавить смещение в ASCII «a»? Это экономит выделение памяти и, на мой взгляд, более яснее.

+1

Это справедливый вопрос. Я предполагаю, что респонденты пытались свести к минимуму количество нового материала, представленного (очевидному) начинающему вопросу. Вы увидите, что «вокруг этих частей; добро пожаловать в SO. – msw

+0

Две причины выскакивают на меня. Во-первых, вы не уверены, что '' a '+ 1 ==' b''. Во-вторых, это не особенно расширяемо. Что делать, если вам нужны цифры или заглавные буквы? Или и то, и другое, но без нижнего ящика или капитала О, потому что они выглядят как цифры? Простота решения на основе массива более чем перевешивает небольшие накладные расходы на дополнительные шестьдесят или около того байтов данных. –

+0

Достаточно справедливо. Спасибо за понимание. – babbitt

0

Для полноты:

std::vector<char> BuildKey(std::size_t keyLength) 
{ 
    const char elements[] = "[email protected]_"; 
    const std::size_t numElements = sizeof(elements)/sizeof(char); 
     //division technically superfluous, as sizeof(char) == 1, but in general its needed. 

    std::vector<char> key; 
    key.reserve(keyLength); 
    for(std::size_t i = 0; i < keyLength; ++i) 
     key.push_back(elements[rand()%numElements]); 
    //there are a handful of ways using standard algorithms to achieve this, 
    // but I'm largely unconvinced the added complexity is justified for simple loops 

    return key; 
} 

Есть еще несколько изменений можно сделать. Я, вероятно, буду параметризировать rand, поэтому я могу позже выбрать PRNG и, возможно, предоставить массив elements в качестве ввода. И string может быть более подходящим, чем vector в зависимости от того, как вы планируете использовать ключ. Или просто примите ForwardIterator и верните void. Много вариантов.

Смежные вопросы