source

C++에서 임의의 영숫자 문자열을 만들려면 어떻게 해야 합니까?

factcode 2023. 10. 11. 21:03
반응형

C++에서 임의의 영숫자 문자열을 만들려면 어떻게 해야 합니까?

알파벳 문자로 구성된 임의의 문자열을 만들고 싶습니다.저는 문자열의 길이를 지정할 수 있기를 원합니다.

C++에서는 어떻게 하는 거죠?

메흐르다드 아프샤리의 대답이 효과가 있겠지만, 저는 이 간단한 일을 하기에는 너무 장황하다고 생각했습니다.룩업 테이블은 때때로 놀라운 효과를 발휘할 수 있습니다.

#include <ctime>
#include <iostream>
#include <unistd.h>

std::string gen_random(const int len) {
    static const char alphanum[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
    std::string tmp_s;
    tmp_s.reserve(len);

    for (int i = 0; i < len; ++i) {
        tmp_s += alphanum[rand() % (sizeof(alphanum) - 1)];
    }
    
    return tmp_s;
}

int main(int argc, char *argv[]) {
    srand((unsigned)time(NULL) * getpid());     
    std::cout << gen_random(12) << "\n";        
    return 0;
}

:rand 품질이 떨어지는 난수를 생성합니다.

C++11을 이용한 아테스 고랄의 답변을 각색한 글입니다.여기에 람다를 추가했지만, 원칙은 이를 전달하여 문자열에 포함된 문자를 제어할 수 있다는 것입니다.

std::string random_string( size_t length )
{
    auto randchar = []() -> char
    {
        const char charset[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
        const size_t max_index = (sizeof(charset) - 1);
        return charset[ rand() % max_index ];
    };
    std::string str(length,0);
    std::generate_n( str.begin(), length, randchar );
    return str;
}

다음은 임의 문자열 함수에 람다를 전달하는 예입니다. http://ideone.com/Ya8EKf

C++11을 사용합니까?

  1. 원하는 문자 집합에 대해 특정 확률 분포(또는 분포 조합)를 따르는 문자열을 생성할 수 있기 때문입니다.
  2. 비결정적 난수에 대한 지원이 내장되어 있기 때문입니다.
  3. 유니코드를 지원하기 때문에 국제화 버전으로 변경할 수 있습니다.

예를 들어,

#include <iostream>
#include <vector>
#include <random>
#include <functional> //for std::function
#include <algorithm>  //for std::generate_n

typedef std::vector<char> char_array;

char_array charset()
{
    //Change this to suit
    return char_array( 
    {'0','1','2','3','4',
    '5','6','7','8','9',
    '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',
    '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'
    });
};    

// given a function that generates a random character,
// return a string of the requested length
std::string random_string( size_t length, std::function<char(void)> rand_char )
{
    std::string str(length,0);
    std::generate_n( str.begin(), length, rand_char );
    return str;
}

int main()
{
    //0) create the character set.
    //   yes, you can use an array here, 
    //   but a function is cleaner and more flexible
    const auto ch_set = charset();

    //1) create a non-deterministic random number generator      
    std::default_random_engine rng(std::random_device{}());

    //2) create a random number "shaper" that will give
    //   us uniformly distributed indices into the character set
    std::uniform_int_distribution<> dist(0, ch_set.size()-1);

    //3) create a function that ties them together, to get:
    //   a non-deterministic uniform distribution from the 
    //   character set of your choice.
    auto randchar = [ ch_set,&dist,&rng ](){return ch_set[ dist(rng) ];};

    //4) set the length of the string you want and profit!        
    auto length = 5;
    std::cout<<random_string(length,randchar)<<std::endl;
    return 0;
}

샘플 출력.

나의 2p 솔루션:

#include <random>
#include <string>

std::string random_string(std::string::size_type length)
{
    static auto& chrs = "0123456789"
        "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    thread_local static std::mt19937 rg{std::random_device{}()};
    thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);

    std::string s;

    s.reserve(length);

    while(length--)
        s += chrs[pick(rg)];

    return s;
}

수동으로 루핑하는 것보다는 적절한 C++ 알고리즘을 사용하는 것이 좋습니다. 이 경우 적절한 난수 생성기를 사용하는 것이 좋습니다.

auto generate_random_alphanumeric_string(std::size_t len) -> std::string {
    static constexpr auto chars =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
    thread_local auto rng = random_generator<>();
    auto dist = std::uniform_int_distribution{{}, std::strlen(chars) - 1};
    auto result = std::string(len, '\0');
    std::generate_n(begin(result), len, [&]() { return chars[dist(rng)]; });
    return result;
}

이것은 제가 이 문제에 대해 "정통적인" 해결책이라고 부르는 것에 가깝습니다.

불행하게도 일반적인 C++ 난수 생성기(예: MT19937)올바르게 시드하는 것은 매우 어렵습니다.따라서 위 코드는 도우미 기능 템플릿을 사용합니다.random_generator:

template <typename T = std::mt19937>
auto random_generator() -> T {
    auto constexpr seed_bytes = sizeof(typename T::result_type) * T::state_size;
    auto constexpr seed_len = seed_bytes / sizeof(std::seed_seq::result_type);
    auto seed = std::array<std::seed_seq::result_type, seed_len>();
    auto dev = std::random_device();
    std::generate_n(begin(seed), seed_len, std::ref(dev));
    auto seed_seq = std::seed_seq(begin(seed), end(seed));
    return T{seed_seq};
}

이것은 복잡하고 상대적으로 비효율적입니다.운이 좋게도 그것은 a를 초기화하는 데 사용됩니다.thread_local 한 됩니다.됩니다.

마지막으로, 위에 필요한 것들은 다음과 같습니다.

#include <algorithm>
#include <array>
#include <cstring>
#include <functional>
#include <random>
#include <string>

위 코드는 클래스 템플릿 인수 차감을 사용하므로 C++17이 필요합니다.필요한 템플릿 인수를 추가하여 이전 버전에 맞게 약간 조정할 수 있습니다.

 void gen_random(char *s, size_t len) {
     for (size_t i = 0; i < len; ++i) {
         int randomChar = rand()%(26+26+10);
         if (randomChar < 26)
             s[i] = 'a' + randomChar;
         else if (randomChar < 26+26)
             s[i] = 'A' + randomChar - 26;
         else
             s[i] = '0' + randomChar - 26 - 26;
     }
     s[len] = 0;
 }

방금 테스트해봤는데 달콤하게 작동하고 조회 테이블이 필요 없습니다. rand_alnum()은 영숫자를 일종의 힘으로 사용하지만 가능한 256자 중에서 62자를 선택하기 때문에 큰 문제가 되지 않습니다.

#include <cstdlib>   // for rand()
#include <cctype>    // for isalnum()   
#include <algorithm> // for back_inserter
#include <string>

char 
rand_alnum()
{
    char c;
    while (!std::isalnum(c = static_cast<char>(std::rand())))
        ;
    return c;
}


std::string 
rand_alnum_str (std::string::size_type sz)
{
    std::string s;
    s.reserve  (sz);
    generate_n (std::back_inserter(s), sz, rand_alnum);
    return s;
}

누군가에게 도움이 되었으면 좋겠습니다.

C++ 4.9.2로 https://www.codechef.com/ide 에서 테스트됨

#include <iostream>
#include <string>
#include <stdlib.h>     /* srand, rand */

using namespace std;

string RandomString(int len)
{
   string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   string newstr;
   int pos;
   while(newstr.size() != len) {
    pos = ((rand() % (str.size() - 1)));
    newstr += str.substr(pos,1);
   }
   return newstr;
}

int main()
{
   srand(time(0));
   string random_str = RandomString(100);
   cout << "random_str : " << random_str << endl;
}

Output: random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd

재미있는 짤막한 짤막한 짤막한 짤막한 짤막한 짤막한 짤막한 짤막ASCII가 필요합니다.

void gen_random(char *s, int l) {
    for (int c; c=rand()%62, *s++ = (c+"07="[(c+16)/26])*(l-->0););
}

표준 라이브러리에서 가장 적합한 함수는 std::sample입니다.

#include <algorithm>
#include <iterator>
#include <random>
#include <string>
#include <iostream>

static const char charset[] = 
    "0123456789"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz";

template<typename URBG>
std::string gen_string(std::size_t length, URBG&& g) {
    std::string result;
    result.resize(length);
    std::sample(std::cbegin(charset), 
                std::cend(charset),
                std::begin(result),
                std::intptr_t(length),
                std::forward<URBG>(g));
    return result;
}

int main() {
    std::mt19937 g;
    std::cout << gen_string(10, g) << std::endl;
    std::cout << gen_string(10, g) << std::endl;
}

난수 생성기의 상태는 호출 간 기능 밖에 있어야 합니다.

#include <iostream>
#include <string>
#include <random>

std::string generateRandomId(size_t length = 0)
{
    static const std::string allowed_chars {"123456789BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz"};

    static thread_local std::default_random_engine randomEngine(std::random_device{}());
    static thread_local std::uniform_int_distribution<int> randomDistribution(0, allowed_chars.size() - 1);

    std::string id(length ? length : 32, '\0');

    for (std::string::value_type& c : id) {
        c = allowed_chars[randomDistribution(randomEngine)];
    }

    return id;
}

int main()
{
    std::cout << generateRandomId() << std::endl;
}

아무렇게나 편리하게 다시 만들어요!

저는 멋진 C++11 헤더 전용 솔루션을 만들었습니다.프로젝트에 하나의 헤더 파일을 쉽게 추가한 다음 테스트를 추가하거나 다른 목적으로 임의 문자열을 사용할 수 있습니다.

빠른 설명이지만 링크를 따라 전체 코드를 확인할 수 있습니다.솔루션의 주요 부분은 Randomer 클래스에 있습니다.

class Randomer {
    // random seed by default
    std::mt19937 gen_;
    std::uniform_int_distribution<size_t> dist_;

public:
    /* ... some convenience ctors ... */

    Randomer(size_t min, size_t max, unsigned int seed = std::random_device{}())
        : gen_{seed}, dist_{min, max} {
    }

    // if you want predictable numbers
    void SetSeed(unsigned int seed) {
        gen_.seed(seed);
    }

    size_t operator()() {
        return dist_(gen_);
    }
};

Randomer모든 랜덤한 것들을 캡슐화하고 여러분은 그것에 여러분만의 기능을 쉽게 추가할 수 있습니다.에 먹고.Randomer가 매우 .

std::string GenerateString(size_t len) {
    std::string str;
    auto rand_char = [](){ return alphabet[randomer()]; };
    std::generate_n(std::back_inserter(str), len, rand_char);
    return str;
}

개선을 위한 제안을 아래에 적으세요.https://gist.github.com/VjGusev/e6da2cb4d4b0b531c1d009cd1f8904ad

문자열에 인쇄 가능한 문자가 포함되어 있으면 더 간단하면서도 기본적인 정보를 얻을 수 있습니다.

#include <time.h>   // we'll use time for the seed
#include <string.h> // this is for strcpy

void randomString(int size, char* output) // pass the destination size and the destination itself
{
    srand(time(NULL)); // seed with time

    char src[size];
    size = rand() % size; // this randomises the size (optional)

    src[size] = '\0'; // start with the end of the string...

    // ...and work your way backwards
    while(--size > -1)
        src[size] = (rand() % 94) + 32; // generate a string ranging from the space character to ~ (tilde)

    strcpy(output, src); // store the random string
}

Qt 사용 예:)

QString random_string(int length=32, QString allow_symbols=QString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")) {
    QString result;
    qsrand(QTime::currentTime().msec());
    for (int i = 0; i < length; ++i) {            
        result.append(allow_symbols.at(qrand() % (allow_symbols.length())));
    }
    return result;
}

그러나 또 다른 적응은 어떤 대답도 제 요구에 충분하지 않을 것이기 때문입니다.

만약 ,rand()난수를 생성하는 데 사용됩니다. 각 실행 시 동일한 출력을 얻을 수 있습니다.난수 생성기의 시드는 일종의 난수여야 합니다.

C++11을 사용하면 다음을 포함할 수 있습니다.random 할 수 .random_device그리고.mt19937 시계 이 시드는 OS에 의해 공급될 것이고 우리에게 충분히 무작위적일 것입니다(예를 들어 시계).내 경우에 포함될 범위 경계를 지정할 수 있습니다([0,25]).

의 임의 해서 를 사용했습니다.char추가. 에게 맞지 .캐릭터 풀 접근 방식은 저에게 맞지 않았습니다.

#include <random>    
void gen_random(char *s, const int len){
    static std::random_device rd;
    static std::mt19937 mt(rd());
    static std::uniform_int_distribution<int> dist(0, 25);
    for (int i = 0; i < len; ++i) {
        s[i] = 'a' + dist(mt);
    }
    s[len] = 0;
}

random() 메서드를 사용하여 기본 랜덤 문자열을 생성할 수 있습니다.아래 코드는 소문자, 대문자 및 숫자로 구성된 랜덤 문자열을 생성합니다.

String randomStrGen(int numChars){
  String genStr="";
  int sizeStr=0;
  
  while(sizeStr<numChars){
    int asciiPos= random(48,122);
    if((asciiPos>57 && asciiPos<65) || (asciiPos>90 && asciiPos<97))
      continue;
    genStr+=(char) asciiPos;
    sizeStr++;
  }
  
  return genStr;
}

더 안전한 난수 생성기가 필요하다면, 더 안전한 난수 생성기를 위해 난수 () 함수를 교체하기만 하면 됩니다.

또한 ASCII 제한(48,122)을 다른 사용자 지정 값으로 변경하여 생성할 수 있는 문자를 조정할 수도 있습니다.

랜덤 문자열, 모든 실행 파일 = 다른 문자열

        auto randchar = []() -> char
    {
        const char charset[] =
            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
            "abcdefghijklmnopqrstuvwxyz";

        const size_t max_index = (sizeof(charset) - 1);

        return charset[randomGenerator(0, max_index)];
    };
            std::string custom_string;
            size_t LENGTH_NAME = 6 // length of name
    generate_n(custom_string.begin(), LENGTH_NAME, randchar);

기능 호출 시 주의해야 합니다.

string gen_random(const int len) {
static const char alphanum[] = "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

stringstream ss;

for (int i = 0; i < len; ++i) {
    ss << alphanum[rand() % (sizeof(alphanum) - 1)];
}
return ss.str();
}

(@Ates Goral을 각색) 매번 동일한 문자 수열이 생성됩니다. 사용합니다.

srand(time(NULL));

함수를 호출하기 전에 rand () 함수는 항상 1 @kjfletch로 시드됩니다.

예:

void SerialNumberGenerator() {

    srand(time(NULL));
    for (int i = 0; i < 5; i++) {
        cout << gen_random(10) << endl;
    }
}
#include <iostream>
#include <string>
#include <stdlib.h>
int main()
{
    int size;
    std::cout << "Enter size : ";
    std::cin >> size;
    std::string str;
    for (int i = 0; i < size; i++)
    {
        auto d = rand() % 26 + 'a';
        str.push_back(d);
    }
    for (int i = 0; i < size; i++)
    {
        std::cout << str[i] << '\t';
    }

    return 0;
}
void strGetRandomAlphaNum(char *sStr, unsigned int iLen)
{
  char Syms[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  unsigned int Ind = 0;
  srand(time(NULL) + rand());
  while(Ind < iLen)
  {
    sStr[Ind++] = Syms[rand()%62];
  }
  sStr[iLen] = '\0';
}
//C++ Simple Code
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<char> alphanum =
    {'0','1','2','3','4',
'5','6','7','8','9',
'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',
'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'
};
string s="";
int len=5;
srand(time(0)); 
for (int i = 0; i <len; i++) {
    int t=alphanum.size()-1;
    int idx=rand()%t;
    s+= alphanum[idx];
}
cout<<s<<" ";
return 0;
}

언급URL : https://stackoverflow.com/questions/440133/how-do-i-create-a-random-alpha-numeric-string-in-c

반응형