[c자작] gen_random_string() 함수를 만들어보셈 2
흑마법사(118.216)
2021-02-12 01:11
추천 0
srand() 에 seed 값으로 gettimeofday 에서 usec 과 time(NULL) 하면 나오는 sec 곱해서 넣어줬고요.
왜냐믄, usec 값만으로는 값 범위 자체가 너무 적어서 그랬어유~~
이번 예제에서는 오바플로우는 여부는 신경 안 써도 되구요.
글구 유심히 봐두면 좋은게..
char *p;
uint32_t random;
p = (char *) &random; 요고요.
&random 이렇게 하면 주소값으로 변환되는 건 다들 알죠?
근데 고렇게하면 uint32_t * 이런 형태니까..
그걸 다시 (char *) 이렇게 캐스팅해서
p = (char *) &random;
이렇게 됩니다.
uint32_t random 은 4바이트 저장공간이에요.
그래서 p[0] 부터 p[3] 까지 총 1바이트씩 4개 공간. 이렇게만 접근해야 오류 안 나요.
출력 가능한 아스키문자 범위는 32부터 126까지이고.
이렇게 해서 출력하면 랜덤 문자열 길이가 최대 4가 되니까...
너무 적겠다 싶어서 그걸 limit 만큼 반복시켰습니다.
그래서 문자열 길이 최대값이 8 * 4 = 32 가 됩니다
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
char *gen_random_string
()
{
uint32_t random
;
uint8_t pos
= 0;
uint8_t limit
= 8;
char *str
;
char *p
;
struct timeval tv
;
str
= malloc
(sizeof (uint32_t) * limit
+ sizeof (char));
gettimeofday
(&tv
, NULL);
srand
(tv
.tv_usec
* time
(NULL));
for (uint8_t j
= 0; j
< limit
; j
++)
{
random
= rand
();
p
= (char *) &random
;
for (uint8_t i
= 0; i
< 4; i
++)
{
if (p
[i
] >= 32 && p
[i
] <= 126)
{
str
[pos
] = p
[i
];
pos
++;
}
}
}
str
[pos
] = 0;
return str
;
}
int main(int argc
, char **argv
)
{
char *str
;
str
= gen_random_string
();
puts
(str
);
free
(str
);
return 0;
}
참 쉽죠잉?
이렇게 쉬운 언어가 c 언어입니다.
너 루비야? 자작자작나무
으케 아셨씨융
님 50대인거 사실임?
나는 2117 년에서 왔음. 100세 넘음 ㅋㅋ
동정 을 100세 까지 유지해서 흑마법사가 그됬군ㄷ
아.. 이거 설명 안 했네.. str[pos] = 0; 이거는 문자열 맨 끝에 '\0' 넣어주는 겁니다. null-terminated string 이게 되는거죠. 널로 끝나는 문자열. 문자열 마지막 끝에는 모두 널로 끝나야 되용. 안 그러면 오류 떨어지유~~~ 글구 malloc 해줄 때도 예를 들어 hello 는 문자열 길이(strlen)가 5가 되는다 우리가 malloc 써서 직접 그런걸 만들 때에는 5 + 1해야 함. hello 끝에 0 을 붙이는거죠 0 은 '\0' 이거에요^^
네
뭐야 이건.. 쉬운걸 괜히 타입 여러개 써서 어려운척 현혹시켜놨네
문소리~~ 원래 쉬운걸~~
rand() 가 uint32_t 를 리턴하느데~ 타입 변환 안 하고 고고?
그냥 int로 하면되자나.. 요즘은.. 그냥 int로하면 에러나? 안한지가 오래되서 모르겟네 ..
pos, limit, for 안에 i 는 그냥 int 써도 됨. 근데 uint8_t 써도 되구
uint32_t random 은 uint32_t 꼭 써야됨. 글고 char *p 이런 것도 char * 꼭 써야 되구, (char *) &random 에서 (char *) 꼭 써야되구. 다른거 쓰면 크기 안 맞아서 오류남.
uint32_t 가 4바이트인데.. uint32_t * 이걸로는 1바이트씩 접근 못함. 그래서 char * 로 char 사이즈인 1바이트씩 접근할 수 있는거지
uint32_t *p; p++ 하면 sizeof(uint32_t) 만큼 증가됨. char *p; p++ 하면 sizeof(char) 만큼 증가됨. 둘다 1씩 증가하는게 아니라 sizeof (type) 만큼 증가하는거임
아~~ 님 말이 맞네 man 3 rand 보니 반환형이 int 네. 내가 착각을 핶구나. uint32_t 대신에 그냥 int 쓰는게 낫겠네. for 문 안에 sizeof(int) 이렇게 해주면 호환성 문제도 없을 거 같구
아예 문자열이 안 나올수도 있는데 걍 p[i] % 95 + 32 하면 안됨?
오호~~ 이 방법 좋네~~ 님 천재임^^
근데 해보니까 편향되네. p[i] 값 범위가.. 0..0xff 까지니까. 편향됨