0

I have been tasked with implementing a simple substitution encryption scheme for which I am given an encoder.

The program below is for the Mac even though I have been instructed to make the program compile and run in Visual Studio for Windows.

My reason is that I own a Mac and thought it would be just as well to write the program on whichever machine I like, then make the adjustments where necessary. It's only a console mode app after all.

I didn't expect is how the program behaves on a Mac:

On the Mac the seed quite simply appears not to work. It keeps on producing new permutations even though I have only used two different seeds.

Visual Studio on Windows generated the expected result of producing a permutation unique to each seed value. Does srand simply mean nothing with respect to the random_shuffle function on a Mac, unlike on a PC?

Code below, followed by output cut and paste. Both from Mac X-Code 7.2 compilation.

So, basically, why doesn't srand(seed) do what's expected?

/code

#include <string>
#include <cstdlib>
#include "algorithm"
#include <iostream>

using namespace std;

const string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,í ";

string cp(unsigned seed) {
    srand(seed);
    string permutation = ALPHABET;
    // using built-in random generator:
    random_shuffle(permutation.begin(), permutation.end());
    return permutation;
}

int main(int argc, char** argv) {

    unsigned seedy = 100;
    string what = cp(seedy);
    cout << what << endl;

    seedy = 200;
    what = cp(seedy);
    cout << what << endl;

    seedy = 100;
    what = cp(seedy);
    cout << what << endl;

    seedy = 100;
    what = cp(seedy);
    cout << what << endl;

    getchar();

    return 0;
}

/code

Console output:

'XQACKHSLOJ,TRBZNGV.W FIUEYDMP

OILQPNSWBAHYGTD'EFKV,XMR. CJZU

J,DKXTHP'RQOEZCYG. SMFIULABVNW

WNJTCYA EHSDPQLKO.ZURGF,'VMIBX

Georgina Davenport
  • 189
  • 1
  • 2
  • 11
  • http://stackoverflow.com/a/22482118/2836621 – Mark Setchell Mar 09 '16 at 18:43
  • I just glanced on the problem, but, are you sure that dealing with non-ASCII characters are good in all platforms considered? – wesley.mesquita Mar 09 '16 at 18:43
  • There is no single quote in your source text. There is an "í", though, which is not US ASCII. The random generator for random_shuffle is implementation-dependent. – molbdnilo Mar 09 '16 at 18:51
  • Support for Extended ASCII, codes over 127, is so fragmented as to be worthless. Don't count on any portability. Reading again, I think this comment is a rephrasing of @wesley.mesquita 's point. – user4581301 Mar 09 '16 at 18:53
  • The non ascii \' is a problem, but one I can solve easily by substitution. The real anomalies are the failure of the srand value, which may well have been answered by Mark Setchell. But leaves me wondering if it can be seeded in any way? and the additional character in the output string which indicates a functional difference between iterator manipulation on the two platforms. Is anybody able to answer those questions please? – Georgina Davenport Mar 09 '16 at 19:24
  • 1
    In UTF8 encoding, the "í" character maps to two bytes, in octal 0303 and 0255. The shuffle is moving the two bytes of this character independently, as if they were two distinct characters. This also destroys the character's encoding. – Christopher Oicles Mar 09 '16 at 19:47
  • Is there anybody left able to explain why the srand doesn't work? And how to replace it with something which does? – Georgina Davenport Mar 09 '16 at 22:40

1 Answers1

2

srand(seed) may or may not impact the result of random_shuffle; it's up to the implementation, so you shouldn't rely on it.

The random_shuffle function uses an unspecified source of randomness. This may be rand() or it may be something completely different; likely the C++ standard library implementation used by Visual Studio uses rand(), while the implementation you're using on OS X is using a different source of randomness.

If you really need it to use rand() internally, you can pass a unary function as the third parameter, to tell it how to generate random numbers for the shuffle:

random_shuffle(permutation.begin(), permutation.end(), [](int x) { return rand() % x; });
Collin Dauphinee
  • 13,664
  • 1
  • 40
  • 71