Вы находитесь на странице: 1из 5

Sequential GUIDs in C++ with Qt - CodeProject https://www.codeproject.com/Tips/594304/Sequen...

12,825,530 members (36,337 online) Sign in

Search for articles, questions, tips

home articles quick answers discussions features community help

Articles Platforms, Frameworks & Libraries Cross Platform Qt

Sequential GUIDs in C++ with Qt


computermagic, 17 May 2013 CPOL Rate this:
0.00 (No votes)

Generating sequential GUIDs in C++ and Qt 5

Introduction
Generate sequential GUIDs in C++ using the Qt framework. This is a rewrite of the existing C# article here (http://www.codeproject.com
/Articles/388157/GUIDs-as-fast-primary-keys-under-multiple-database). That article contains an excellent description of why you would
want sequential GUIDs.

This code is written specifically for Qt 5.

Background
Databases insert sequential information quickly. When you insert information out of order it requires the database to rebuild indexes
which can be time consuming. Get the advantages of sequential numbering for you database records while getting the benefit of unique
ids that a GUID gives.

Source Code - sequenatialguid.h


Hide Shrink Copy Code

#ifndef SEQUENTIALGUID_H
#define SEQUENTIALGUID_H

#include <QObject>
#include <QUuid>
#include <QByteArray>
#include <QDateTime>
#include <QDataStream>
#include <QTime>

class SequentialGUID : public QObject


{
Q_OBJECT
public:
explicit SequentialGUID(QObject *parent = 0);

enum SequentialGUIDType {
SequentialAsString = 0,
SequentialAsBinary = 1,
SequentialAtEnd = 2
};

static QUuid GetSequentialGUID(SequentialGUIDType guid_type);

signals:

public slots:

private:

1 of 5 18/04/17 11:52
Sequential GUIDs in C++ with Qt - CodeProject https://www.codeproject.com/Tips/594304/Sequen...

static void InitRand();


static int randInt(int low, int high);

static bool rand_init;


};

#endif // SEQUENTIALGUID_H

Source Code - sequentialguid.cpp


Hide Shrink Copy Code

#include "sequentialguid.h"

// Declare static variables


bool SequentialGUID::rand_init = false;

SequentialGUID::SequentialGUID(QObject *parent) :
QObject(parent)
{
}

void SequentialGUID::InitRand() {
if (!rand_init) {
QTime t = QTime::currentTime();
qsrand((uint) t.msec());

rand_init = true;
}
}

int SequentialGUID::randInt(int low, int high) {


InitRand();
return qrand() % ((high+1) - low) + low;
}

QUuid SequentialGUID::GetSequentialGUID(SequentialGUIDType guid_type)


{
QByteArray randBytes;
// Get some random bytes
for(int i=0; i<10; i++) {
char b = (char)randInt(0, 255);
randBytes.append(b);
}
// Would prefer a cryptographically secure rng
// _rng.GetBytes(randBytes);

//long timestamp = QDateTime::Now.Ticks / 10000L;


qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
QByteArray timestampBytes;
timestampBytes.resize(sizeof(timestamp));
QByteArray timestampBytesRev;
timestampBytesRev.resize(sizeof(timestamp));

char *ptr = (char *)&timestamp;


for(int i=0; i<8; i++) {
timestampBytes[i] = ptr[i];
timestampBytesRev[7-i] = ptr[i];
}
// We only want 48 bytes, cut off high bytes which should be 0's anyway
// unless this is the future...
timestampBytes.remove(6, 2);
timestampBytesRev.remove(0,2);

QByteArray tsBytes;

// Use the correct endian so we get a proper sequence (e.g. counting up digits
// on the right so it sorts properly in the database)
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
tsBytes = timestampBytesRev;
#else
tsBytes = timestampBytes;
#endif

QByteArray guidBytes;

switch (guid_type) {

2 of 5 18/04/17 11:52
Sequential GUIDs in C++ with Qt - CodeProject https://www.codeproject.com/Tips/594304/Sequen...

case SequentialAsString:
case SequentialAsBinary:
guidBytes.append(tsBytes);
guidBytes.append(randBytes);
break;

case SequentialAtEnd:
guidBytes.append(randBytes);
guidBytes.append(tsBytes);
break;
}

QUuid uid = QUuid::fromRfc4122(guidBytes);


return uid;
}

Using the code


Include the sequentialguid.h file so you can use the object in your application:
Hide Copy Code
#include "sequentialguid.h"

Get a new GUID this way:


Hide Copy Code
<span style="font-size: 9pt;">QUuid guid =
SequentialGUID::GetSequentialGUID(SequentialGUID::SequentialAsString);</span>

Points of Interest
Random numbers are NOT generated using a cryptographically secure method. For my particular case, this wasn't important. The
original article used the .Net framework System.Security.Cryptography.RNGCryptoServiceProvider(); to do so. I didn't
know the code to do so in C++ off the top of my head.

The parameter SequentialGUID::SequentialAsString can be replaced with SequentialAsBinary, or SequentialAtEnd.

Rule of thumb us to use SequentialAtEnd for MSSql servers, and the others for most other database systems (look under "Using The
Code" section in original article for a description).

Here is an example of sequential GUIDs

History
5/17/2013 - Initial posting of code

License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

3 of 5 18/04/17 11:52
Sequential GUIDs in C++ with Qt - CodeProject https://www.codeproject.com/Tips/594304/Sequen...

EMAIL TWITTER

About the Author


computermagic

President Computer Magic And Software Design


United States

We specialize in custom software development for your business. With 10+ years of experience,
you can be be sure that you are getting the best code that money can buy.

You may also be interested in...


Pro High performance with IoT Reference Implementation:
distributed caching How to Build an Environment
Monitor Solution

Sequential GUIDS in Python Doorbell in Python

Technical Guide on C Visual COBOL New Release:


Small point. Big deal

Comments and Discussions

You must Sign In to use this message board.

Search Comments Go

Spacing Relaxed Layout Normal Per page 25 Update

First Prev Next

A better implementation for Qt users? Member 10915356 30-Jun-14 18:10

Last Visit: 31-Dec-99 19:00 Last Update: 28-Mar-17 4:18 Refresh 1

General News Suggestion Question Bug Answer Joke Praise Rant Admin

4 of 5 18/04/17 11:52
Sequential GUIDs in C++ with Qt - CodeProject https://www.codeproject.com/Tips/594304/Sequen...

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile Layout: fixed | Article Copyright 2013 by computermagic
Web02 | 2.8.170308.1 | Last Updated 17 May 2013 Seleccionar idioma fluid Everything else Copyright CodeProject, 1999-2017

5 of 5 18/04/17 11:52

Вам также может понравиться