再 ABCの乱数編

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
しょしょしょしんしゃ

再 ABCの乱数編

#1

投稿記事 by しょしょしょしんしゃ » 16年前

C言語 乱数と文字列

学校の宿題ですが
乱数を使用して、文字列を作成するのですが
分かりません。問題は以下のとおりです。

ランダムな文字列を作成する関数void passwd()作成
1、使用できる文字はアルファベット大文字のAからZ,小文字のaからzおよび数字の2から9の合計60文字。
2、文字列の長さは7文字から10文字のランダムに決められた値とする。
3、文字列に大文字・小文字・数字すべてが入っている文字列しか生成しない。
  たとえば、E4F7ukYはいいが、kuh8ghandは大文字がないので、やり直しという風です。


分かりにくい部分がありますが、よろしくお願いします。
一応、条件1、2はクリアできたのですが、条件3のやり直しする部分をどのようにするか分かりません、
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main (void){
 int nc; 
 char pwd[11]; 
 int n; 
 char c; 
 int k; 
 char yn[2]; 

 srand((unsigned)time(NULL));
      nc = 7+rand()%4;
      n = 0;
do{
k=rand()%3;
switch(k){
case 0:
c='2'+rand()%8;break;
case 1:
c='a'+rand()%26;break;
case 2:
c='A'+rand()%26;break;
}
pwd[n++] = c;
}while(n<nc);
pwd[n]='\0';
printf("生成されたパスワード:%s\n",pwd);
return 0;
}
 

Mist

Re:再 ABCの乱数編

#2

投稿記事 by Mist » 16年前

while(1) {
    パスワード作成

  完成したパスワードをチェック
  →OK break;
}
でいいと思いますが。

バグ

Re:再 ABCの乱数編

#3

投稿記事 by バグ » 16年前

1:大文字から1文字を選択
2:小文字から1文字を選択
3:数字から1文字を選択
4:残り部分を大文字・小文字・数字から選択
5:シャッフル

でいいんでは?
この方法なら、文字列の判定が不要になり、その結果として、やり直す事も考慮する必要がなくなります。

バグ

Re:再 ABCの乱数編

#4

投稿記事 by バグ » 16年前

私が書き込みしたアルゴリズムで実装すると、こんな感じでしょうか?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* A~Zから1文字を取得する関数 */
char getAlphabetBig()
{
	return 'A' + (char)(rand() % 26);
}

/* a~zから1文字を取得する関数 */
char getAlphabetSmall()
{
	return 'a' + (char)(rand() % 26);
}

/* 2~9から1文字を取得する関数 */
char getNumber()
{
	return '2' + (char)(rand() % 8);
}

/* A~Z、a~z、2~9の中から1文字を取得する関数 */
char getAllSymbol()
{
	switch (rand() % 3)
	{
	case 0:
		return getAlphabetBig();
	case 1:
		return getAlphabetSmall();
	default:
		return getNumber();
	}
}

/* 文字列をシャッフルする */
void shuffleString(char* pwd)
{
	char buf = '\0';
	unsigned int i;
	int swap;

	for (i = 0; i < strlen(pwd); ++i)
	{
		/* ランダムに選択された箇所の文字と入れ替える */
		swap = rand() % strlen(pwd);
		buf = pwd;
		pwd = pwd[swap];
		pwd[swap] = buf;
	}
}

int main(void)
{
	char pwd[11] = {'\0', };
	int i;

	srand((unsigned)time(NULL));

	/* 最初の3文字には大文字、小文字、数字を各1文字ずつ選択する */
	pwd[0] = getAlphabetBig();
	pwd[1] = getAlphabetSmall();
	pwd[2] = getNumber();

	/* 残りの7文字は大文字、小文字、数字の全ての中から選択する */
	for (i = 3; i < 10; ++i)
	{
		pwd = getAllSymbol();
	}

	/* 文字列をシャッフルする */
	shuffleString(pwd);

	/* 文字列の表示 */
	printf("生成されたパスワード:%s\n", pwd);
}

lbfuvab

Re:再 ABCの乱数編

#5

投稿記事 by lbfuvab » 16年前

こんな感じですかね。(間違ってる可能性あり)
const char str[60]="qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM23456789";

char GetBigAlpha(void){
    return str[rand()%26];
}
char GetSmlAlpha(void){
    return str[26+rand()%26];
}
char GetNum(void){
    return str[52+rand()%8];
}
char GetRndCh(void){
    return str[rand()%60];
}
int __cdecl RndCmp(void* a,void *b){
    return (rand()%2)?1:-1;
}

void Password(char *buf){
    int len=7+rand()%4,i=0;
    
    buf[i++]=GetBigAlpha();
    buf[i++]=GetSmlAlpha();
    buf[i++]=GetNum();
    
    for(;i<len;i++)
        buf=GetRndCh();
    
    qsort(buf,(size_t)len,sizeof(char),RndCmp);
}

non

Re:再 ABCの乱数編

#6

投稿記事 by non » 16年前

>たとえば、E4F7ukYはいいが、kuh8ghandは大文字がないので、やり直しという風です。
やり直しって指示があるなら、やり直しした方がいいでしょう。
なるべく、本人が作った部分を壊さないように作りました。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main (void)
{
	int nc; 
	char pwd[11]; 
	int n; 
	char c; 
	int k; 
	char yn[2];
	unsigned char  sw=0; //何が使われたかのスイッチ 
	srand((unsigned)time(NULL));
	while(sw!=0x07){  // 3つのビットが1になるまで繰り返し
 		n=0;
		nc = 7+rand()%4;
		do{
			k=rand()%3;
			switch(k){
				case 0:
				sw |=0x01; // 0ビット目を1にする
				c='2'+rand()%8;break;
				case 1:
				sw |=0x02; // 1ビット目を1にする
				c='a'+rand()%26;break;
				case 2:
				sw |=0x04; // 2ビット目を1にする
				c='A'+rand()%26;break;
			}
			pwd[n++] = c;
		}while(n<nc);
		pwd[n]='\0';
	}
	printf("生成されたパスワード:%s\n",pwd);
	return 0;
}

Mist

Re:再 ABCの乱数編

#7

投稿記事 by Mist » 16年前

やり直したときのswの再初期化が抜けてると思う。

non

Re:再 ABCの乱数編

#8

投稿記事 by non » 16年前

あら、本当だ。失礼しました。
どこに入れれば、いいかはわかりますよね。

しょしょしょしんしゃ

Re:再 ABCの乱数編

#9

投稿記事 by しょしょしょしんしゃ » 16年前

遅くなりましたが、
興味深い プログラムの例文ありがとうございました。

おかげ様
で 参考になりました。
また お願いします。

しょしょしょしんしゃ

Re:再 ABCの乱数編

#10

投稿記事 by しょしょしょしんしゃ » 16年前

kaiketu
入れ忘れました。

閉鎖

“C言語何でも質問掲示板” へ戻る