Generating random text

closed account (SECMoG1T)
Hi, i need some help, i would like to generate unique random alphanum strings for different products in my application, yesterday i asked this question but i got something close to a solution before anyone replied so i deleted the thread but after examining my solution thoroughly i found that yeah it could give me some random text, not very unique and totally irreproducible, this was not what i wanted

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  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;
}


Is it possible to have a function maybe similar to a hashing function, that will take a class object and assign a random unique string to the object and that function should reproduce the same ID if the object is passed as an argument again

Note: i might have multiple copies of some objects F.E if Bar is an object
of the class Foo then at some instances i might have a container
containing 10 copies of Bar, i would also like to assign unique IDs even
to such objects that are copies of others.

Thanks in advance.
Last edited on
to reproduce random strings you need to have the same seed.

You may have an static int which is a unique id. Each object that participate takes the id and increase it (note that's not thread safe). Then you can use the object id as a seed for random.

Note that setting the global seed influences all random numbers.
closed account (SECMoG1T)
@coder777 that makes sense now
have the same seed,static int which is a unique id, ++ perfect , but say i would also like to have a search function in my application that will search for the object using, this unique string ID, i would like to pass a temporal class object to the function and retrieve the real object mapped to this ID F.E:

1
2
3
4
5
6
7
8
Foo temp;///temporaly object

Foo& search_with_ID(Foo temp)
{
  
  auto obj_id=generate_random(temp);
  return Foo_store[obj_id];///Foo_store is a map object
}



will that be possible, just trying to figure if i can get something like that working.
Last edited on
closed account (SECMoG1T)
Anyone?
I don't know whether I understand what you're trying to do. Why do you need temp? The real object is mapped to what? What is F.E?
closed account (SECMoG1T)
F.E(for example) :<> , leave alone the example above , i might not have explained it perfectly but basically the whole idea was to use the unique ID to ease the look up like we do using bar/Qr codes.
Last edited on
You may have [a] static int which is a unique id.

You could also use the object's address as a unique ID. This is easier but it won't work if the objects can be moved in memory, such as when writing them out to a file and reading them back in during a subsequent run of the program.

Say i would also like to have a search function in my application that will search for the object using, this unique string ID
Use an std::map<> to map string ID to object address.

closed account (SECMoG1T)
Surely @dhyden i intend to use a map to store the objects but on the other hand my challenges are on the rises , am also sure that my objects will certainly be moved in memory from time to time so using the address as the ID presents yet another challenge

This are the reasons why i needed this ID

1. be able to differentiate between similar objects :- think of a store or a library
you might have 100 copies of the book "Effective STL" or whatever else that can be
stocked in there, how would you be able to differentiate between each of those copies.

2. Ease look up -
I might want to check if one of those copies is still in stock, i would not like to loop
100 or so times while i can access the item in O(1) using the ID.
closed account (SECMoG1T)
I just need some ideas on how to get this working.
> I just need some ideas on how to get this working.

A few ideas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <string>
#include <random>
#include <ctime>
#include <map>
#include <functional>
#include <algorithm>

struct object
{
    const std::string id ;

    static const object& cget( const std::string& id ) { return get(id) ; }
    static object& get( const std::string& id )
    {
        const auto iter = id_map.find(id) ;
        if( iter == id_map.end() ) throw std::out_of_range( "id '" + id + "' not found" ) ;
        return *iter->second ;
    }

    object( int v = 0 ) : id( random_unique_id() ), value(v) { id_map.emplace( id, this ) ; }
    object( const object& that ) : object( that.value ) {} // ids are not copied
    object( object&& that ) noexcept : object( that.value ) {}
    object& operator= ( const object& that ) { value = that.value ; return *this ; }
    object& operator= ( object&& that ) noexcept { value = that.value ; return *this ; }
    ~object() { id_map.erase(id) ; }

    static std::map< std::string, object* const > id_map ;
    static const std::size_t ID_SIZE = 8 ;
    static std::string random_unique_id() ;

    int value ;
};

std::map< std::string, object* const > object::id_map ;

std::string object::random_unique_id()
{
    static std::mt19937 rng( std::time(nullptr) ) ;
    static std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ;

    std::shuffle( std::begin(alphabet), std::end(alphabet), rng ) ;
    std::string candidate = alphabet.substr( 0, ID_SIZE ) ;
    return id_map.find(candidate) == id_map.end() ? candidate : random_unique_id() ;
}

int main()
{
    object seq[4] ;
    for( const object& obj : seq ) std::cout << obj.id << ' ' << std::addressof(obj) << '\n' ;

    object x = seq[2] ;
    const std::string id_x = x.id ;
    std::cout << id_x << ' ' << object::get(id_x).id << ' '
              << std::addressof(x) << ' ' << std::addressof( object::get(id_x) ) << '\n'
              << seq[2].id << ' ' << seq+2 << ' ' << std::addressof( object::cget( seq[2].id ) ) << '\n';
}

http://coliru.stacked-crooked.com/a/10a0f1b78904fe05
closed account (SECMoG1T)
Thank you very much @JLBorges lemmi take my time n study this carefully, i'll ask a question if I get one .
Last edited on
Topic archived. No new replies allowed.