multicloud365
  • Home
  • Cloud Architecture
    • OCI
    • GCP
    • Azure
    • AWS
    • IAC
    • Cloud Networking
    • Cloud Trends and Innovations
    • Cloud Security
    • Cloud Platforms
  • Data Management
  • DevOps and Automation
    • Tutorials and How-Tos
  • Case Studies and Industry Insights
    • AI and Machine Learning in the Cloud
No Result
View All Result
  • Home
  • Cloud Architecture
    • OCI
    • GCP
    • Azure
    • AWS
    • IAC
    • Cloud Networking
    • Cloud Trends and Innovations
    • Cloud Security
    • Cloud Platforms
  • Data Management
  • DevOps and Automation
    • Tutorials and How-Tos
  • Case Studies and Industry Insights
    • AI and Machine Learning in the Cloud
No Result
View All Result
multicloud365
No Result
View All Result

PL/SQL package deal for 64-bit xoshiro/xoroshiro pseudorandom quantity turbines

admin by admin
March 27, 2025
in OCI
0
Creation of Code 2024 – Day 1
399
SHARES
2.3k
VIEWS
Share on FacebookShare on Twitter


Persevering with within the path of earlier two posts, the package deal under helps all the xoshiro/xoroshiro algorithms returning 64-bit values.

  • xoroshiro128+
  • xoroshiro128++
  • xoroshiro128**
  • xoshiro256+
  • xoshiro256++
  • xoshiro256**
  • xoshiro512+
  • xoshiro512++
  • xoshiro512**
  • xoroshiro1024*
  • xoroshiro1024++
  • xoroshiro1024**

The numbers within the names seek advice from the dimensions of the state array that every methodology operates on.

Utilizing every of them follows the identical sample:

  1. Select the algorithm mode (the package deal defaults to xoshiro256++)
  2. Seed the state array
  3. Retrieve the subsequent quantity from the chosen algorithm as many instances as wanted

For instance…

SQL> BEGIN
  2      xoshiro.set_mode('xoroshiro128++');
  3      xoshiro.set_state(xoshiro.seed_tab(12345, 67890));
  4
  5      FOR i IN 0 .. 9
  6      LOOP
  7          DBMS_OUTPUT.put_line(i || ' ' || LPAD(xoshiro.get_next, 10));
  8      END LOOP;
  9  END;
 10  /
0 1051657426
1 9791286188
2 9989489894
3 6590593871
4 6705930516
5 1618779258
6 8800234758
7 2334047907
8 8330851765
9 3477959413

Optionally, you may name the bounce or long_jump features to bounce forward within the state by simulating many (from 2^64 to 2^768 relying on the mode and bounce measurement) calls of the get_next operate. As famous by Blackman and Vigna, these are sometimes used to generate non-overlapping sequences for parallel processing. In single threaded use there can be no want for them.

Along with these I additionally included the splitmix64 operate which is, itself, a pseudo-random quantity generator and can be utilized in an identical method. Set the seed, after which name the splitmix64_next to retrieve the subsequent quantity.

SQL> BEGIN
  2      xoshiro.splitmix64_set_state(12345);
  3
  4      FOR i IN 0 .. 9
  5      LOOP
  6          DBMS_OUTPUT.put_line(i || ' ' || LPAD(xoshiro.splitmix64_next, 10));
  7      END LOOP;
  8  END;
  9  /
0 2454886589
1 3778200017
2 2205171434
3 3248800117
4 9350289611
5 6217189988
6 2262534019
7 7959005890
8 8850488307
9 1600295491

This isn’t the everyday utilization although. Moderately, splitmix64 is usually recommended as a way of seeding the state arrays of the opposite algorithms. Under, I set the splitmix64 state, after which create a seed of 4 values for the xoshiro256** generator.

SQL> DECLARE
  2      v_seed   xoshiro.seed_tab := xoshiro.seed_tab();
  3  BEGIN
  4      xoshiro.splitmix64_set_state(12345);
  5      v_seed.EXTEND(4);
  6
  7      FOR i IN 1 .. 4
  8      LOOP
  9          v_seed(i) := xoshiro.splitmix64_next;
 10      END LOOP;
 11
 12      xoshiro.set_mode('xoshiro256**');
 13      xoshiro.set_state(v_seed);
 14
 15      FOR i IN 0 .. 9
 16      LOOP
 17          DBMS_OUTPUT.put_line(i || ' ' || LPAD(xoshiro.get_next, 10));
 18      END LOOP;
 19  END;
 20  /
0 1372083882
1 2398916695
2 1777038484
3 8917177268
4 1024131604
5 1969754298
6 2947371003
7 5456629693
8 7119811276
9 1679784635

Following is the whole package deal for all the 64-bit algorithms.

CREATE OR REPLACE PACKAGE xoshiro
IS
    -- Based mostly on xoshiro/xoroshiro household of pseudorandom quantity turbines
    --  by by David Blackman and Sebastiano Vigna
    -- unique  https://prng.di.unimi.it

    --                    .///.
    --                   (0 o)
    ---------------0000--(_)--0000---------------
    --
    --  Sean D. Stuber
    --  sean.stuber@gmail.com
    --
    --             oooO      Oooo
    --------------(   )-----(   )---------------
    --              (       ) /
    --              _)     (_/

    -- It will be good to outline an express RANGE 0..18446744073709551615 for the subtype
    -- however as of 23ai, solely subtypes of PLS_INTEGER could have a variety.
    SUBTYPE uint64_t IS NUMBER(20, 0);

    TYPE seed_tab IS TABLE OF uint64_t;

    SUBTYPE bits_t IS SIMPLE_INTEGER RANGE 0 .. 63;

    SUBTYPE mode_t IS SIMPLE_INTEGER RANGE 1 .. 12;

    c_128plus        CONSTANT mode_t := 1; -- xoroshiro128+
    c_128plusplus    CONSTANT mode_t := 2; -- xoroshiro128++
    c_128starstar    CONSTANT mode_t := 3; -- xoroshiro128**

    c_256plus        CONSTANT mode_t := 4; -- xoshiro256+
    c_256plusplus    CONSTANT mode_t := 5; -- xoshiro256++
    c_256starstar    CONSTANT mode_t := 6; -- xoshiro256**

    c_512plus        CONSTANT mode_t := 7; -- xoshiro512+
    c_512plusplus    CONSTANT mode_t := 8; -- xoshiro512++
    c_512starstar    CONSTANT mode_t := 9; -- xoshiro512**

    c_1024star       CONSTANT mode_t := 10; -- xoroshiro1024*
    c_1024plusplus   CONSTANT mode_t := 11; -- xoroshiro1024++
    c_1024starstar   CONSTANT mode_t := 12; -- xoroshiro1024**

    --Exceptions
    invalid_mode              EXCEPTION;

    -- Choose a mode by numeric worth or by identify
    PROCEDURE set_mode(p_mode IN mode_t);
    PROCEDURE set_mode(p_mode IN VARCHAR2);

    -- Return the present mode quantity or identify
    FUNCTION get_mode
        RETURN mode_t;
    FUNCTION get_mode_name
        RETURN VARCHAR2;

    -- Given a set of seed values, initialize the state array for the present mode measurement
    -- Totally different modes for a selected measurement can share the identical state array.
    PROCEDURE set_state(p_seed IN seed_tab);

    -- Return the subsequent pseudorandom generator worth for the present mode
    FUNCTION get_next
        RETURN uint64_t;

    -- Simulate many calls to "get_next".  Sometimes used to create non-overlapping sequences from the identical preliminary state.
    PROCEDURE bounce;

    -- Simulate much more calls to "get_next".  Additionally used to create non-overlapping sequences from the identical preliminary state.
    PROCEDURE long_jump;

    -- SplitMix64 is not a part of the xoshiro/xoroshiro household
    -- Nonetheless utilizing it to fill the state arrays as an alternative of a easy integer
    -- is really useful by the unique authors.
    PROCEDURE splitmix64_set_state(p_seed uint64_t);

    FUNCTION splitmix64_next
        RETURN uint64_t;
END;

As a comparability reference for myself and readers, I included snippets of the unique c code throughout the feedback of the package deal physique for the varied procedures and features of every mode.

CREATE OR REPLACE PACKAGE BODY xoshiro
IS
    c_64bitmask   CONSTANT uint64_t := POWER(2, 64) - 1;

    SUBTYPE array_128index_t IS PLS_INTEGER RANGE 0 .. 1;

    SUBTYPE array_256index_t IS PLS_INTEGER RANGE 0 .. 3;

    SUBTYPE array_512index_t IS PLS_INTEGER RANGE 0 .. 7;

    SUBTYPE array_1024index_t IS PLS_INTEGER RANGE 0 .. 15;

    TYPE state128_array_t IS TABLE OF uint64_t
        INDEX BY array_128index_t;

    TYPE state256_array_t IS TABLE OF uint64_t
        INDEX BY array_256index_t;

    TYPE state512_array_t IS TABLE OF uint64_t
        INDEX BY array_512index_t;

    TYPE state1024_array_t IS TABLE OF uint64_t
        INDEX BY array_1024index_t;

    g_mode                 mode_t := c_256plusplus;

    g_splitmix64_state     uint64_t;

    g_128_state            state128_array_t; -- xoroshiro128+, xoroshiro128++, xoroshiro128**
    g_256_state            state256_array_t; -- xoshiro256+, xoshiro256++, xoshiro256**
    g_512_state            state512_array_t; -- xoshiro512+, xoshiro512++, xoshiro512**
    g_1024_state           state1024_array_t; --  xoroshiro1024*,  xoroshiro1024++,  xoroshiro1024**

    -- Used to index into the state array for the 1024bit modes
    g_1024_p               array_1024index_t := 0;

    FUNCTION bitor(p_a IN uint64_t, p_b IN uint64_t)
        RETURN uint64_t
    IS
    BEGIN
        RETURN BITAND(p_a + p_b - BITAND(p_a, p_b), c_64bitmask);
    END bitor;

    FUNCTION bitxor(p_a IN uint64_t, p_b IN uint64_t)
        RETURN uint64_t
    IS
    BEGIN
        RETURN BITAND((p_a + p_b) - (BITAND(p_a, p_b) * 2), c_64bitmask);
    END bitxor;

    FUNCTION big_bitand(p_a IN NUMBER, p_b IN NUMBER)
        RETURN NUMBER
    IS
        v_result        NUMBER;
        v_temp          NUMBER;
        v_a_shift       NUMBER;
        v_b_shift       NUMBER;
        v_a_first_bit   NUMBER;
        v_b_first_bit   NUMBER;
    BEGIN
        -- Oracle's native BITAND  operate has an higher restrict of energy(2,127)-1
        CASE
            WHEN p_a > (64 - ok));
    -- }
    BEGIN
        RETURN CASE WHEN p_k = 0 THEN p_x ELSE bitor(shl64(p_x, p_k), shr64(p_x, 64 - p_k)) END;
    END rotl;

    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------

    FUNCTION next128plus
        RETURN uint64_t
    IS
        --  uint64_t subsequent(void) {
        --   const uint64_t s0 = s[0];
        --   uint64_t s1 = s[1];
        --   const uint64_t outcome = s0 + s1;
        --
        --   s1 ^= s0;
        --   s[0] = rotl(s0, 24) ^ s1 ^ (s1  TO_NUMBER('df900294d8f554a5', 'xxxxxxxxxxxxxxxx'),
                                        1   => TO_NUMBER('170865df4b3201fc', 'xxxxxxxxxxxxxxxx'))
                   WHEN g_mode = c_128plusplus
                   THEN
                       state128_array_t(0   => TO_NUMBER('2bd7a6a6e99c2ddc', 'xxxxxxxxxxxxxxxx'),
                                        1   => TO_NUMBER('0992ccaf6a6fca05', 'xxxxxxxxxxxxxxxx'))
               END;
        v_s0      uint64_t := 0;
        v_s1      uint64_t := 0;
        v_dummy   uint64_t;
    BEGIN
        FOR i IN 0 .. 1
        LOOP
            FOR b IN 0 .. 63
            LOOP
                IF BITAND(v_jump(i), shl64(1, b)) != 0
                THEN
                    v_s0 := bitxor(v_s0, g_128_state(0));
                    v_s1 := bitxor(v_s1, g_128_state(1));
                END IF;

                v_dummy := next128;
            END LOOP;
        END LOOP;

        g_128_state(0) := v_s0;
        g_128_state(1) := v_s1;
    END jump128;

    PROCEDURE long_jump128
    IS
        -- xoroshiro128+ and xoroshiro128** use the identical lengthy bounce array

        -- /* That is the long-jump operate for the generator. It's equal to
        --    2^96 calls to subsequent(); it may be used to generate 2^32 beginning factors,
        --    from every of which bounce() will generate 2^32 non-overlapping
        --    subsequences for parallel distributed computations. */
        --
        -- void long_jump(void) {
        --  static const uint64_t LONG_JUMP[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 };
        --
        --  uint64_t s0 = 0;
        --  uint64_t s1 = 0;
        --  for(int i = 0; i  TO_NUMBER('d2a98b26625eee7b', 'xxxxxxxxxxxxxxxx'),
                                        1   => TO_NUMBER('dddf9b1090aa7ac1', 'xxxxxxxxxxxxxxxx'))
                   WHEN g_mode = c_128plusplus
                   THEN
                       state128_array_t(0   => TO_NUMBER('360fd5f2cf8d5d99', 'xxxxxxxxxxxxxxxx'),
                                        1   => TO_NUMBER('9c6e6877736c46e3', 'xxxxxxxxxxxxxxxx'))
               END;

        v_s0         uint64_t := 0;
        v_s1         uint64_t := 0;
        v_dummy      uint64_t;
    BEGIN
        FOR i IN 0 .. 1
        LOOP
            FOR b IN 0 .. 63
            LOOP
                IF BITAND(v_longjump(i), shl64(1, b)) != 0
                THEN
                    v_s0 := bitxor(v_s0, g_128_state(0));
                    v_s1 := bitxor(v_s1, g_128_state(1));
                END IF;

                v_dummy := next128;
            END LOOP;
        END LOOP;

        g_128_state(0) := v_s0;
        g_128_state(1) := v_s1;
    END long_jump128;

    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------

    FUNCTION next256
        RETURN uint64_t
    IS
        -- The outcome for the present state is calculated in another way for every mode
        -- however the steps to increment the state for the subsequent worth are the identical

        --  const uint64_t outcome = s[0] + s[3];                   -- xoshiro256+
        --  const uint64_t outcome = rotl(s[0] + s[3], 23) + s[0];  -- xoshiro256++
        --  const uint64_t outcome = rotl(s[1] * 5, 7) * 9;         -- xoshiro256**

        --  uint64_t subsequent(void) {
        --   const uint64_t outcome = s[0] + s[3];
        --
        --   const uint64_t t = s[1]  TO_NUMBER('180ec6d33cfd0aba', 'xxxxxxxxxxxxxxxx'),
                                1   => TO_NUMBER('d5a61266f0c9392c', 'xxxxxxxxxxxxxxxx'),
                                2   => TO_NUMBER('a9582618e03fc9aa', 'xxxxxxxxxxxxxxxx'),
                                3   => TO_NUMBER('39abdc4529b1661c', 'xxxxxxxxxxxxxxxx')) ;

        v_s0              uint64_t := 0;
        v_s1              uint64_t := 0;
        v_s2              uint64_t := 0;
        v_s3              uint64_t := 0;
        v_dummy           uint64_t;
    BEGIN
        FOR i IN 0 .. 3
        LOOP
            FOR b IN 0 .. 63
            LOOP
                IF BITAND(v_jump(i), shl64(1, b)) != 0
                THEN
                    v_s0 := bitxor(v_s0, g_256_state(0));
                    v_s1 := bitxor(v_s1, g_256_state(1));
                    v_s2 := bitxor(v_s2, g_256_state(2));
                    v_s3 := bitxor(v_s3, g_256_state(3));
                END IF;

                v_dummy := next256;
            END LOOP;
        END LOOP;

        g_256_state(0) := v_s0;
        g_256_state(1) := v_s1;
        g_256_state(2) := v_s2;
        g_256_state(3) := v_s3;
    END jump256;

    PROCEDURE long_jump256
    IS
        --  /* That is the long-jump operate for the generator. It's equal to
        --     2^192 calls to subsequent(); it may be used to generate 2^64 beginning factors,
        --     from every of which bounce() will generate 2^64 non-overlapping
        --     subsequences for parallel distributed computations. */
        --
        --  void long_jump(void) {
        --   static const uint64_t LONG_JUMP[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 };
        --
        --   uint64_t s0 = 0;
        --   uint64_t s1 = 0;
        --   uint64_t s2 = 0;
        --   uint64_t s3 = 0;
        --   for(int i = 0; i  TO_NUMBER('76e15d3efefdcbbf', 'xxxxxxxxxxxxxxxx'),
                                1   => TO_NUMBER('c5004e441c522fb3', 'xxxxxxxxxxxxxxxx'),
                                2   => TO_NUMBER('77710069854ee241', 'xxxxxxxxxxxxxxxx'),
                                3   => TO_NUMBER('39109bb02acbe635', 'xxxxxxxxxxxxxxxx')) ;

        v_s0                  uint64_t := 0;
        v_s1                  uint64_t := 0;
        v_s2                  uint64_t := 0;
        v_s3                  uint64_t := 0;
        v_dummy               uint64_t;
    BEGIN
        FOR i IN 0 .. 3
        LOOP
            FOR b IN 0 .. 63
            LOOP
                IF BITAND(v_longjump(i), shl64(1, b)) != 0
                THEN
                    v_s0 := bitxor(v_s0, g_256_state(0));
                    v_s1 := bitxor(v_s1, g_256_state(1));
                    v_s2 := bitxor(v_s2, g_256_state(2));
                    v_s3 := bitxor(v_s3, g_256_state(3));
                END IF;

                v_dummy := next256;
            END LOOP;
        END LOOP;

        g_256_state(0) := v_s0;
        g_256_state(1) := v_s1;
        g_256_state(2) := v_s2;
        g_256_state(3) := v_s3;
    END long_jump256;

    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------

    FUNCTION next512
        RETURN uint64_t
    IS
        -- The outcome for the present state is calculated in another way for every mode
        -- however the steps to increment the state for the subsequent worth are the identical

        --  const uint64_t outcome = s[0] + s[2];                   -- xoshiro512+
        --  const uint64_t outcome = rotl(s[0] + s[2], 17) + s[2];  -- xoshiro512++
        --  const uint64_t outcome = rotl(s[1] * 5, 7) * 9;         -- xoshiro512**

        --  uint64_t subsequent(void) {
        --   const uint64_t outcome = s[0] + s[2];
        --
        --   const uint64_t t = s[1]  TO_NUMBER('33ed89b6e7a353f9', 'xxxxxxxxxxxxxxxx'),
                                1   => TO_NUMBER('760083d7955323be', 'xxxxxxxxxxxxxxxx'),
                                2   => TO_NUMBER('2837f2fbb5f22fae', 'xxxxxxxxxxxxxxxx'),
                                3   => TO_NUMBER('4b8c5674d309511c', 'xxxxxxxxxxxxxxxx'),
                                4   => TO_NUMBER('b11ac47a7ba28c25', 'xxxxxxxxxxxxxxxx'),
                                5   => TO_NUMBER('f1be7667092bcc1c', 'xxxxxxxxxxxxxxxx'),
                                6   => TO_NUMBER('53851efdb6df0aaf', 'xxxxxxxxxxxxxxxx'),
                                7   => TO_NUMBER('1ebbc8b23eaf25db', 'xxxxxxxxxxxxxxxx')) ;
        v_t               state512_array_t := state512_array_t(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0);

        v_dummy           uint64_t;
    BEGIN
        FOR i IN 0 .. 7
        LOOP
            FOR b IN 0 .. 63
            LOOP
                IF BITAND(v_jump(i), shl64(1, b)) != 0
                THEN
                    FOR w IN 0 .. 7
                    LOOP
                        v_t(w) := bitxor(v_t(w), g_512_state(w));
                    END LOOP;
                END IF;

                v_dummy := next512;
            END LOOP;
        END LOOP;

        FOR i IN 0 .. 7
        LOOP
            g_512_state(i) := v_t(i);
        END LOOP;
    END jump512;

    PROCEDURE long_jump512
    IS
        --  /* That is the long-jump operate for the generator. It's equal to
        --     2^384 calls to subsequent(); it may be used to generate 2^128 beginning factors,
        --     from every of which bounce() will generate 2^128 non-overlapping
        --     subsequences for parallel distributed computations. */
        --
        --  void long_jump(void) {
        --   static const uint64_t LONG_JUMP[] = { 0x11467fef8f921d28, 0xa2a819f2e79c8ea8, 0xa8299fc284b3959a, 0xb4d347340ca63ee1, 0x1cb0940bedbff6ce, 0xd956c5c4fa1f8e17, 0x915e38fd4eda93bc, 0x5b3ccdfa5d7daca5 };
        --
        --   uint64_t t[sizeof s / sizeof *s];
        --   memset(t, 0, sizeof t);
        --   for(int i = 0; i  TO_NUMBER('11467fef8f921d28', 'xxxxxxxxxxxxxxxx'),
                                1   => TO_NUMBER('a2a819f2e79c8ea8', 'xxxxxxxxxxxxxxxx'),
                                2   => TO_NUMBER('a8299fc284b3959a', 'xxxxxxxxxxxxxxxx'),
                                3   => TO_NUMBER('b4d347340ca63ee1', 'xxxxxxxxxxxxxxxx'),
                                4   => TO_NUMBER('1cb0940bedbff6ce', 'xxxxxxxxxxxxxxxx'),
                                5   => TO_NUMBER('d956c5c4fa1f8e17', 'xxxxxxxxxxxxxxxx'),
                                6   => TO_NUMBER('915e38fd4eda93bc', 'xxxxxxxxxxxxxxxx'),
                                7   => TO_NUMBER('5b3ccdfa5d7daca5', 'xxxxxxxxxxxxxxxx')) ;
        v_t                   state512_array_t
                                  := state512_array_t(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0);
        v_dummy               uint64_t;
    BEGIN
        FOR i IN 0 .. 7
        LOOP
            FOR b IN 0 .. 63
            LOOP
                IF BITAND(v_longjump(i), shl64(1, b)) != 0
                THEN
                    FOR w IN 0 .. 7
                    LOOP
                        v_t(w) := bitxor(v_t(w), g_512_state(w));
                    END LOOP;
                END IF;

                v_dummy := next512;
            END LOOP;
        END LOOP;

        FOR i IN 0 .. 7
        LOOP
            g_512_state(i) := v_t(i);
        END LOOP;
    END long_jump512;

    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------

    FUNCTION next1024
        RETURN uint64_t
    IS
        -- The outcome for the present state is calculated in another way for every mode
        -- however the steps to increment the state for the subsequent worth are the identical

        --  const uint64_t outcome = s0 * 0x9e3779b97f4a7c13;      -- xoshiro1024*
        --  const uint64_t outcome = rotl(s0 + s15, 23) + s15;     -- xoshiro1024++
        --  cconst uint64_t outcome = rotl(s0 * 5, 7) * 9;         -- xoshiro1024**

        --  uint64_t subsequent(void) {
        --   const int q = p;
        --   const uint64_t s0 = s[p = (p + 1) & 15];
        --   uint64_t s15 = s[q];
        --   const uint64_t outcome = s0 * 0x9e3779b97f4a7c13;
        --
        --   s15 ^= s0;
        --   s[q] = rotl(s0, 25) ^ s15 ^ (s15  TO_NUMBER('931197d8e3177f17', 'xxxxxxxxxxxxxxxx'),
                                                   1    => TO_NUMBER('b59422e0b9138c5f', 'xxxxxxxxxxxxxxxx'),
                                                   2    => TO_NUMBER('f06a6afb49d668bb', 'xxxxxxxxxxxxxxxx'),
                                                   3    => TO_NUMBER('acb8a6412c8a1401', 'xxxxxxxxxxxxxxxx'),
                                                   4    => TO_NUMBER('12304ec85f0b3468', 'xxxxxxxxxxxxxxxx'),
                                                   5    => TO_NUMBER('b7dfe7079209891e', 'xxxxxxxxxxxxxxxx'),
                                                   6    => TO_NUMBER('405b7eec77d9eb14', 'xxxxxxxxxxxxxxxx'),
                                                   7    => TO_NUMBER('34ead68280c44e4a', 'xxxxxxxxxxxxxxxx'),
                                                   8    => TO_NUMBER('e0e4ba3e0ac9e366', 'xxxxxxxxxxxxxxxx'),
                                                   9    => TO_NUMBER('8f46eda8348905b7', 'xxxxxxxxxxxxxxxx'),
                                                   10   => TO_NUMBER('328bf4dbad90d6ff', 'xxxxxxxxxxxxxxxx'),
                                                   11   => TO_NUMBER('c8fd6fb31c9effc3', 'xxxxxxxxxxxxxxxx'),
                                                   12   => TO_NUMBER('e899d452d4b67652', 'xxxxxxxxxxxxxxxx'),
                                                   13   => TO_NUMBER('45f387286ade3205', 'xxxxxxxxxxxxxxxx'),
                                                   14   => TO_NUMBER('03864f454a8920bd', 'xxxxxxxxxxxxxxxx'),
                                                   15   => TO_NUMBER('a68fa28725b1b384', 'xxxxxxxxxxxxxxxx')) ;
        v_t               state1024_array_t
                              := state1024_array_t(0    => 0,
                                                   1    => 0,
                                                   2    => 0,
                                                   3    => 0,
                                                   4    => 0,
                                                   5    => 0,
                                                   6    => 0,
                                                   7    => 0,
                                                   8    => 0,
                                                   9    => 0,
                                                   10   => 0,
                                                   11   => 0,
                                                   12   => 0,
                                                   13   => 0,
                                                   14   => 0,
                                                   15   => 0);

        v_dummy           uint64_t;
    BEGIN
        FOR i IN 0 .. 15
        LOOP
            FOR b IN 0 .. 63
            LOOP
                IF BITAND(v_jump(i), shl64(1, b)) != 0
                THEN
                    FOR j IN 0 .. 15
                    LOOP
                        v_t(j) := bitxor(v_t(j), g_1024_state(BITAND(j + g_1024_p, 15)));
                    END LOOP;
                END IF;

                v_dummy := next1024;
            END LOOP;
        END LOOP;

        FOR i IN 0 .. 15
        LOOP
            g_1024_state(BITAND(i + g_1024_p, 15)) := v_t(i);
        END LOOP;
    END jump1024;

    PROCEDURE long_jump1024
    IS
        --  /* That is the long-jump operate for the generator. It's equal to
        --     2^768 calls to subsequent(); it may be used to generate 2^256 beginning factors,
        --     from every of which bounce() will generate 2^256 non-overlapping
        --     subsequences for parallel distributed computations. */
        --
        --  void long_jump(void) {
        --   static const uint64_t LONG_JUMP[] = { 0x7374156360bbf00f,
        --    0x4630c2efa3b3c1f6, 0x6654183a892786b1, 0x94f7bfcbfb0f1661,
        --    0x27d8243d3d13eb2d, 0x9701730f3dfb300f, 0x2f293baae6f604ad,
        --    0xa661831cb60cd8b6, 0x68280c77d9fe008c, 0x50554160f5ba9459,
        --    0x2fc20b17ec7b2a9a, 0x49189bbdc8ec9f8f, 0x92a65bca41852cc1,
        --    0xf46820dd0509c12a, 0x52b00c35fbf92185, 0x1e5b3b7f589e03c1 };
        --
        --   uint64_t t[sizeof s / sizeof *s];
        --   memset(t, 0, sizeof t);
        --   for(int i = 0; i  TO_NUMBER('7374156360bbf00f', 'xxxxxxxxxxxxxxxx'),
                                                       1    => TO_NUMBER('4630c2efa3b3c1f6', 'xxxxxxxxxxxxxxxx'),
                                                       2    => TO_NUMBER('6654183a892786b1', 'xxxxxxxxxxxxxxxx'),
                                                       3    => TO_NUMBER('94f7bfcbfb0f1661', 'xxxxxxxxxxxxxxxx'),
                                                       4    => TO_NUMBER('27d8243d3d13eb2d', 'xxxxxxxxxxxxxxxx'),
                                                       5    => TO_NUMBER('9701730f3dfb300f', 'xxxxxxxxxxxxxxxx'),
                                                       6    => TO_NUMBER('2f293baae6f604ad', 'xxxxxxxxxxxxxxxx'),
                                                       7    => TO_NUMBER('a661831cb60cd8b6', 'xxxxxxxxxxxxxxxx'),
                                                       8    => TO_NUMBER('68280c77d9fe008c', 'xxxxxxxxxxxxxxxx'),
                                                       9    => TO_NUMBER('50554160f5ba9459', 'xxxxxxxxxxxxxxxx'),
                                                       10   => TO_NUMBER('2fc20b17ec7b2a9a', 'xxxxxxxxxxxxxxxx'),
                                                       11   => TO_NUMBER('49189bbdc8ec9f8f', 'xxxxxxxxxxxxxxxx'),
                                                       12   => TO_NUMBER('92a65bca41852cc1', 'xxxxxxxxxxxxxxxx'),
                                                       13   => TO_NUMBER('f46820dd0509c12a', 'xxxxxxxxxxxxxxxx'),
                                                       14   => TO_NUMBER('52b00c35fbf92185', 'xxxxxxxxxxxxxxxx'),
                                                       15   => TO_NUMBER('1e5b3b7f589e03c1', 'xxxxxxxxxxxxxxxx')) ;
        v_t                   state1024_array_t
                                  := state1024_array_t(0    => 0,
                                                       1    => 0,
                                                       2    => 0,
                                                       3    => 0,
                                                       4    => 0,
                                                       5    => 0,
                                                       6    => 0,
                                                       7    => 0,
                                                       8    => 0,
                                                       9    => 0,
                                                       10   => 0,
                                                       11   => 0,
                                                       12   => 0,
                                                       13   => 0,
                                                       14   => 0,
                                                       15   => 0);
        v_dummy               uint64_t;
    BEGIN
        FOR i IN 0 .. 15
        LOOP
            FOR b IN 0 .. 63
            LOOP
                IF BITAND(v_longjump(i), shl64(1, b)) != 0
                THEN
                    FOR j IN 0 .. 15
                    LOOP
                        v_t(j) := bitxor(v_t(j), g_1024_state(BITAND(j + g_1024_p, 15)));
                    END LOOP;
                END IF;

                v_dummy := next1024;
            END LOOP;
        END LOOP;

        FOR i IN 0 .. 15
        LOOP
            g_1024_state(BITAND(i + g_1024_p, 15)) := v_t(i);
        END LOOP;
    END long_jump1024;

    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------
    PROCEDURE set_mode(p_mode IN mode_t)
    IS
    BEGIN
        g_mode := p_mode;
    END set_mode;

    PROCEDURE set_mode(p_mode IN VARCHAR2)
    IS
    BEGIN
        set_mode(
            CASE LOWER(p_mode)
                WHEN 'xoroshiro128+' THEN c_128plus
                WHEN 'xoroshiro128++' THEN c_128plusplus
                WHEN 'xoroshiro128**' THEN c_128starstar
                WHEN 'xoshiro256+' THEN c_256plus
                WHEN 'xoshiro256++' THEN c_256plusplus
                WHEN 'xoshiro256**' THEN c_256starstar
                WHEN 'xoshiro512+' THEN c_512plus
                WHEN 'xoshiro512++' THEN c_512plusplus
                WHEN 'xoshiro512**' THEN c_512starstar
                WHEN 'xoroshiro1024*' THEN c_1024star
                WHEN 'xoroshiro1024++' THEN c_1024plusplus
                WHEN 'xoroshiro1024**' THEN c_1024starstar
            END);
    END set_mode;

    FUNCTION get_mode
        RETURN mode_t
    IS
    BEGIN
        RETURN g_mode;
    END get_mode;

    FUNCTION get_mode_name
        RETURN VARCHAR2
    IS
    BEGIN
        RETURN CASE g_mode
                   WHEN c_128plus THEN 'xoroshiro128+'
                   WHEN c_128plusplus THEN 'xoroshiro128++'
                   WHEN c_128starstar THEN 'xoroshiro128**'
                   WHEN c_256plus THEN 'xoshiro256+'
                   WHEN c_256plusplus THEN 'xoshiro256++'
                   WHEN c_256starstar THEN 'xoshiro256**'
                   WHEN c_512plus THEN 'xoshiro512+'
                   WHEN c_512plusplus THEN 'xoshiro512++'
                   WHEN c_512starstar THEN 'xoshiro512**'
                   WHEN c_1024star THEN 'xoroshiro1024*'
                   WHEN c_1024plusplus THEN 'xoroshiro1024++'
                   WHEN c_1024starstar THEN 'xoroshiro1024**'
               END;
    END get_mode_name;

    FUNCTION get_next
        RETURN uint64_t
    IS
    BEGIN
        RETURN CASE
                   WHEN g_mode IN (c_128plus, c_128plusplus, c_128starstar) THEN next128
                   WHEN g_mode IN (c_256plus, c_256plusplus, c_256starstar) THEN next256
                   WHEN g_mode IN (c_512plus, c_512plusplus, c_512starstar) THEN next512
                   WHEN g_mode IN (c_1024star, c_1024plusplus, c_1024starstar) THEN next1024
               END;
    END get_next;

    PROCEDURE bounce
    IS
    BEGIN
        CASE
            WHEN g_mode IN (c_128plus, c_128plusplus, c_128starstar)
            THEN
                jump128;
            WHEN g_mode IN (c_256plus, c_256plusplus, c_256starstar)
            THEN
                jump256;
            WHEN g_mode IN (c_512plus, c_512plusplus, c_512starstar)
            THEN
                jump512;
            WHEN g_mode IN (c_1024star, c_1024plusplus, c_1024starstar)
            THEN
                jump1024;
            ELSE
                RAISE invalid_mode;
        END CASE;
    END bounce;

    PROCEDURE long_jump
    IS
    BEGIN
        CASE
            WHEN g_mode IN (c_128plus, c_128plusplus, c_128starstar)
            THEN
                long_jump128;
            WHEN g_mode IN (c_256plus, c_256plusplus, c_256starstar)
            THEN
                long_jump256;
            WHEN g_mode IN (c_512plus, c_512plusplus, c_512starstar)
            THEN
                long_jump512;
            WHEN g_mode IN (c_1024star, c_1024plusplus, c_1024starstar)
            THEN
                long_jump1024;
            ELSE
                RAISE invalid_mode;
        END CASE;
    END long_jump;

    PROCEDURE set_state(p_seed IN seed_tab)
    IS
    BEGIN
        CASE
            WHEN g_mode IN (c_128plus, c_128plusplus, c_128starstar)
            THEN
                g_128_state := state128_array_t();

                FOR i IN 0 .. 1
                LOOP
                    g_128_state(i) := p_seed(i + 1);
                END LOOP;
            WHEN g_mode IN (c_256plus, c_256plusplus, c_256starstar)
            THEN
                g_256_state := state256_array_t();

                FOR i IN 0 .. 3
                LOOP
                    g_256_state(i) := p_seed(i + 1);
                END LOOP;
            WHEN g_mode IN (c_512plus, c_512plusplus, c_512starstar)
            THEN
                g_512_state := state512_array_t();

                FOR i IN 0 .. 7
                LOOP
                    g_512_state(i) := p_seed(i + 1);
                END LOOP;
            WHEN g_mode IN (c_1024star, c_1024plusplus, c_1024starstar)
            THEN
                g_1024_p := 0;
                g_1024_state := state1024_array_t();

                FOR i IN 0 .. 15
                LOOP
                    g_1024_state(i) := p_seed(i + 1);
                END LOOP;
            ELSE
                RAISE invalid_mode;
        END CASE;
    END set_state;

    PROCEDURE splitmix64_set_state(p_seed uint64_t)
    IS
    BEGIN
        g_splitmix64_state := p_seed;
    END splitmix64_set_state;

    FUNCTION splitmix64_next
        RETURN uint64_t
    IS
        /* Based mostly on the splitmix64.c code by Sebastiano Vigna
              https://xorshift.di.unimi.it/splitmix64.c

             static uint64_t x;

             uint64_t subsequent() {
              uint64_t z = (x += 0x9e3779b97f4a7c15);
              z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
              z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
              return z ^ (z >> 31);
             }

            This won't be almost as quick as the unique because it makes use of division as an alternative of bit shifting.
            Nonetheless, the performance of it must be constant
        */

        v_z   NUMBER;
    BEGIN
        g_splitmix64_state :=
            BITAND(g_splitmix64_state + TO_NUMBER('9e3779b97f4a7c15', 'xxxxxxxxxxxxxxxx'), c_64bitmask);
        v_z := g_splitmix64_state;

        v_z := bitxor(v_z, shr64(v_z, 30));
        v_z := v_z * TO_NUMBER('bf58476d1ce4e5b9', 'xxxxxxxxxxxxxxxx');
        v_z := big_bitand(v_z, c_64bitmask);

        v_z := bitxor(v_z, shr64(v_z, 27));
        v_z := v_z * TO_NUMBER('94d049bb133111eb', 'xxxxxxxxxxxxxxxx');
        v_z := big_bitand(v_z, c_64bitmask);

        RETURN BITAND(bitxor(v_z, shr64(v_z, 31)), c_64bitmask);
    END splitmix64_next;
END;

The BIG_BITAND operate I described intimately beforehand is used throughout the shl64, next1024, and splitmix64_next features to make sure giant (128-bit) values are dealt with accurately.

I hope you discover the code attention-grabbing and helpful. I’ve yet another article deliberate on this collection – protecting the the 32-bit variations inside this generator household. Whereas they may have been mixed right into a single package deal; I felt it was a greater answer to maintain them separate as they’re unlikely for use collectively in sensible utility. Usually I count on customers will need outcomes of a single single bit-size, 64 or 32. Combining them wouldn’t serve a lot objective.

Questions and feedback, as at all times, are welcome.

Tags: 64bitgeneratorsnumberpackagePLSQLpseudorandomxoshiroxoroshiro
Previous Post

Scooter Rental Market Progress Accelerates as City Mobility Evolves

Next Post

6 Google Well being AI updates from The Verify Up occasion 2025

Next Post
6 Google Well being AI updates from The Verify Up occasion 2025

6 Google Well being AI updates from The Verify Up occasion 2025

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Trending

Cloud Safety as a Service (CSaaS): Execs and Cons

Cloud Safety as a Service (CSaaS): Execs and Cons

April 13, 2025
Easy methods to Defend Towards Cyber Assaults Utilizing MITRE ATT&CK

Easy methods to Defend Towards Cyber Assaults Utilizing MITRE ATT&CK

March 20, 2025
An entire Information to create a social media calendar (+Free Templates)

An entire Information to create a social media calendar (+Free Templates)

April 8, 2025
Defending In opposition to UNC3944: Cybercrime Hardening Steering from the Frontlines

Defending In opposition to UNC3944: Cybercrime Hardening Steering from the Frontlines

May 6, 2025
The Rising Market Of Wearable Medicine Adherence Trackers

The Rising Market Of Wearable Medicine Adherence Trackers

February 5, 2025
Automating DevSecOps with Sysdig and PagerDuty

Automating DevSecOps with Sysdig and PagerDuty

March 22, 2025

MultiCloud365

Welcome to MultiCloud365 — your go-to resource for all things cloud! Our mission is to empower IT professionals, developers, and businesses with the knowledge and tools to navigate the ever-evolving landscape of cloud technology.

Category

  • AI and Machine Learning in the Cloud
  • AWS
  • Azure
  • Case Studies and Industry Insights
  • Cloud Architecture
  • Cloud Networking
  • Cloud Platforms
  • Cloud Security
  • Cloud Trends and Innovations
  • Data Management
  • DevOps and Automation
  • GCP
  • IAC
  • OCI

Recent News

Safe & Environment friendly File Dealing with in Spring Boot: Learn, Write, Compress, and Defend | by Rishi | Mar, 2025

Safe & Environment friendly File Dealing with in Spring Boot: Learn, Write, Compress, and Defend | by Rishi | Mar, 2025

May 15, 2025
Bitwarden vs Dashlane: Evaluating Password Managers

Bitwarden vs Dashlane: Evaluating Password Managers

May 15, 2025
  • About Us
  • Privacy Policy
  • Disclaimer
  • Contact

© 2025- https://multicloud365.com/ - All Rights Reserved

No Result
View All Result
  • Home
  • Cloud Architecture
    • OCI
    • GCP
    • Azure
    • AWS
    • IAC
    • Cloud Networking
    • Cloud Trends and Innovations
    • Cloud Security
    • Cloud Platforms
  • Data Management
  • DevOps and Automation
    • Tutorials and How-Tos
  • Case Studies and Industry Insights
    • AI and Machine Learning in the Cloud

© 2025- https://multicloud365.com/ - All Rights Reserved