Skip to content

Global ID (GID)

A Global ID (GID) is a 32-bit identifier used by the client to identify things like forms, images, etc. A GID is typically displayed in one of two formats:

  • Two-Number Format: two numbers separated by a dash (e.g. 32-199)
  • Three-Number Format: three numbers, each separated by a dash (e.g. 1-0-2201)

Regardless of the display format, the numeric value of a GID is the same. That is, it is always a 32-bit value. (1)

  1. Since a GID is just a 32-bit value you could also display it as a single binary, decimal, or hexadecimal number. However when a 32-bit value is used as a GID, it is displayed in two-number or three-number format.

GID Formats

To determine if a GID is displayed in a two or three number format, you need to examine the bits in the high byte (the leftmost 8 bits of the 32-bit value). If any of the bits are set (that is, if any of the bits are 1), then the GID is displayed in a three number format. If none of the bits are set, the GID is displayed in a two number format.

Graphically it looks like:

◀─────────────────────────── 32 bits ───────────────────────────▶

 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1                     
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 
└───────────────┘                                                
        ▲                                                        
        │   If any of these bits are set                         
        └── then display as three numbers                        
            separated by dashes                                  

Stated another way, if the value of the high byte is not 0, then the GID is displayed in three-number format. Otherwise it is displayed in two-number format.

Two-Number Format

When displayed in two-number format, you can think of a GID as a single 32-bit value divided into two halves, called W0 and W1. The W0 field comprises of the high WORD (leftmost 16 bits) and the W1 field comprises the low WORD (rightmost 16 bits).

Graphically it looks like:

◀─────────────────────────── 32 bits ───────────────────────────▶

 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1                     
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 
└───────────────────────────────┴───────────────────────────────┘
                ▲                               ▲                
                │                               │                
               W0                              W1                

In two-number format the first number is contained in W0, and the second number is contained in W1.

For example with the GID 15-201, the value for W0 would be 15 and the value for W1 would be 201. As a single 32-bit value it would be laid out as:

               15                              201               
                │                               │                
                ▼                               ▼                
┌───────────────────────────────┬───────────────────────────────┐
 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 
└───────────────────────────────┴───────────────────────────────┘
                ▲                               ▲                
                │                               │                
               W0                              W1                

Converting a Two-Number GID to a Single Value

To convert a GID displayed in two-number format to a single 32-bit value, you can use the following formulas:

Value = W0 << 16 | W1

or more mathematically...

Value = (W0 * 65536) + W1

For example if the GID is 144-34916, the 32-bit value is 9472100:

Example: GID 144-34916 Converts to Decimal 9472100
Value = (W0  * 65536) + W1
      = (144 * 65536) + 34916
      = 9437184 + 34916
      = 9472100

Converting a Single Value to a Two-Number GID

To do the opposite, that is convert a single value into two-number format, you can use the following formulas:

W0 = Value >> 16
W1 = Value & 0x0000FFFF

The mathematical equivalent is:

W1 = Value % 65356
W0 = (Value - W1) / 65536
Note

The % is the modulo operator, which gives the remainder after division.

For example the 32-bit decimal value 2111065 is the GID 32-13913:

Example: Decimal 286864985 Converts to GID 4377-13913
W1 = Value % 65536
   = 2111065 % 65536
   = 13913

W0 = (Value - W1) / 65536
   = (2111065 - 13913) / 65536
   = 2097152 / 65536
   = 32

Three-Number Format

When displayed in three-number format, you can think of a GID as a single 32-bit value divided into three pieces called B0, B1, and W1. The B0 field is the high BYTE of the high WORD (leftmost 8 bits, of the leftmost 16 bits). The B1 field is the low BYTE of the high WORD (rightmost 8 bits, of the leftmost 16 bits). The W1 field is the low WORD (rightmost 16 bits).

Graphically it looks like:

◀─────────────────────────── 32 bits ───────────────────────────▶

 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1                     
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 
└───────────────┴───────────────┴───────────────────────────────┘
        ▲               ▲                       ▲                
        │               │                       │                
       B0              B1                      W1                

In the three-number format, the first number is B0 the second number is B1, and the third number is W1. For example with the GID 32-0-13743, B0 is 32, B1 is 0, and W1 is 13743.

       32               0                     13743              
        │               │                       │                
        ▼               ▼                       ▼                
┌───────────────┬───────────────┬───────────────────────────────┐
 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 1 1 1 
└───────────────┴───────────────┴───────────────────────────────┘
        ▲               ▲                       ▲                
        │               │                       │                
       B0              B1                      W1                

Converting a Three-Number GID to a Single Value

To convert a GID displayed in three-number format to a single 32-bit value, you can use the following formulas:

Value = ((B0 << 8) | B1) << 16) | W1

for the more mathematically inclined:

Value = (((B0 * 256) + B1) * 65536) + W1

For example if the GID is 118-5-4919 the 32-bit value is 1980044087:

Example: GID 118-5-4919 Converts to Decimal 1980044087
Value = (((B0 * 256) + B1) * 65536) + W1
      = (((118 * 256) + 5) * 65536) + 4919
      = ((30208 + 5) * 65536) + 4919
      = (30213 * 65536) + 4919
      = 1980039168 + 4919
      = 1980044087

Converting a Single Value to a Three-Number GID

To convert a single 32-bit value into a 3-number format GID, you can use the following formuals:

B0 = (Value >> 24) & 0xFF
B1 = (Value >> 16) & 0xFF
W0 = Value & 0x0000FFFF

For the readers who prefer a mathematical approach:

W0 = Value % 65536
B1 = ((Value - W0) / 65536) % 256
B0 = (((Value - W0) / 65536) - B1) / 256

For example the number 673661073 is the GID 40-39-16529:

Example: Decimal 673661073 Converts to GID 40-39-16529
W0 = Value % 65536
   = 673661073 % 65536
   = 16529

B1 = ((Value - W0) / 65536) % 256
   = ((673661073 - 16529) / 65536) % 256
   = (673644544 / 65536) % 256
   = 10279 % 256
   = 39

B0 = (((Value - W0) / 65536) - B1) / 256
   = (((673661073 - 16529) / 65536) - 39) / 256
   = ((673644544 / 65536) - 39) / 256
   = (10279 - 39) / 256
   = 10240 / 256
   = 40

Python Snippets

Here are some Python snippets to implement the concepts described above.

Working With Two- and Three- Number Formats

The first snippet takes in a single number and returns a tuple of two or three numbers, depending on if it should be printed as a two-format GID, or as a three-format GID.

Snippet 1: Convert A Single Value to a GID (tuple)
def from_32bit(value):
    if value & 0xFF000000:
        b0 = (value & 0xFF000000) >> 24
        b1 = (value & 0x00FF0000) >> 16
        w0 = value & 0x0000FFFF
        return b0, b1, w0

    else:
        w0 = (value & 0xFFFF0000) >> 16
        w1 = value & 0x0000FFFF
        return w0, w1

Here is some example output:

>>> from_32bit(32)
(0, 32)
>>> from_32bit(9472100)
(144, 34916)
>>> from_32bit(1980044087)
(118, 5, 4919)

The second snippet takes a single value and returns the GID as a string in either two-number or three-number format accordingly.

Snippet 2: Convert a Single Value to a GID (string)
def gid_str(value):
    if value & 0xFF000000:
        b0 = (value & 0xFF000000) >> 24
        b1 = (value & 0x00FF0000) >> 16
        w1 = value & 0x0000FFFF
        return f'{b0}-{b1}-{w1}'

    else:
        w0 = (value & 0xFFFF0000) >> 16
        w1 = value & 0x0000FFFF
        return f'{w0}-{w1}'

Here is some example output.

>>> gid_str(32)
'0-32'
>>> gid_str(9472100)
'144-34916'
>>> gid_str(1980044087)
'118-5-4919'

The third and fourth snippets take two or three numbers respectively, and in both cases return a single 32-bit value.

Snippet 3: Convert a Two-Number GID to a Single Value
1
2
3
4
5
6
7
8
9
def from_gid2(w0, w1):
    # Make sure w0 and w1 are valid
    if not (0 <= w0 <= 0xFFFF): # (1)!
        raise ValueError(f'Invalid w0 {w0}')
    elif not (0 <= w1 <= 0xFFFF): # (2)!
        raise ValueError(f'Invalid w1 {w1}')

    gid = (w0 << 16) | w1
    return gid
  1. The not inverts the logic, so this will raise an exception if w0 is not between 0 and 0xFFFF inclusive.
  2. The not inverts the logic, so this will raise an exception if w1 is not between 0 and 0xFFFF inclusive.
Snippet 4: Convert Three-Number GID to a Single Value
def from_gid3(b0, b1, w1):
    # Make sure b0, b1, and w1 are valid
    if not (0 <= b0 <= 0xFF): # (1)!
        raise ValueError(f'Invalid b0 {b0}')
    elif not (0 <= b1 <= 0xFF): # (2)!
        raise ValueError(f'Invalid b1 {b1}')
    elif not (0 <= w1 <= 0xFFFF): # (3)!
        raise ValueError(f'Invalid w1 {w1}')

    gid = (b0 << 24) | (b1 << 16) | w1
    return gid
  1. The not inverts the logic, so this will raise an exception if b0 is not between 0 and 0xFF inclusive.
  2. The not inverts the logic, so this will raise an exception if b1 is not between 0 and 0xFF inclusive.
  3. The not inverts the logic, so this will raise an exception if w1 is not between 0 and 0xFFFF inclusive.

Here is some example output:

>>> from_gid2(0, 32)
32
>>> from_gid2(144, 34916)
9472100
>>> from_gid3(118, 5, 4919)
1980044087

With both the from_gid2() and from_gid3() functions, if you to pass invalid values for any of the arguments, you will get an exception:

>>> from_gid2(100000, 25)
ValueError: Invalid w0 100000
>>> from_gid2(25, 500000)
ValueError: Invalid w1 500000
>>> from_gid3(300, 0, 0)
ValueError: Invalid b0 300
>>> from_gid3(0, 300, 0)
ValueError: Invalid b1 300
>>> from_gid3(0, 0, 70000)
ValueError: Invalid w1 70000