2

I'm writing a C# application, where objects are to be identified by their Guid. According to the customer, there should be two types:

  • Standard GUID (128-bit, 36 characters)
  • IFC64 GUID (132-bit, 22 characters)

I believe that the System.Guid corresponds with the first one: System.Guid consists of one int (32-bit), two shorts (each 16-bit) and eight bytes (each 8 bits), which comes together to 32 + 2*16 + 8*8 = 128 bits.

But as far as the so-called IFC64 GUID, I don't find anything.

Does anybody know in which C# library this is defined?

Thanks in advance

Fildor
  • 14,510
  • 4
  • 35
  • 67
Dominique
  • 16,450
  • 15
  • 56
  • 112
  • I don't believe there is a C#/.NET type that implements that IFC-Guid (and comes built-in with any of the frameworks). – Fildor Jul 28 '23 at 08:56
  • Google found me a C-Library on GitHub ... apart from that mostly documentation on the standard itself. You _might_ have to get your hands dirty on that one? – Fildor Jul 28 '23 at 08:59
  • 2
    132 bits? That number is not divisible by 8. So you are saying that some guid wastes bytes for no reason? I don't think there is such thing as 132 bit guid, I tried to Google it but found nothing. The 22 characters correspond to base64 encoding of standard 128 bit guid. – freakish Jul 28 '23 at 09:00
  • @Fildor-standswithMods: Really??? I just had a look at the source code of "Guid.cs" (from `System.Guid`). That's over 1500 lines of code! I hope our customer does not expect us to implement this? – Dominique Jul 28 '23 at 09:01
  • _" I hope our customer does not expect us to implement this?"_ - Well, I don't know _that_. And I only did a quick googledigoog... there may be some library out there. Maybe not on GitHub, maybe closed source, maybe payed ... – Fildor Jul 28 '23 at 09:06
  • @freakish: you might be right: the document from the customer describes `IFC64 Guid` as "132 bit, 22 character", which might mean that a character would be six bits, while it is eight! Next to that, there's an example of a string, consisting of 22 characters indeed. I believe the amount of characters is 22 indeed, but the amount of bits should be 176 instead of 132. This still leaves me with the question if there exists a C# library, covering a `Guid`-like structure, consisting of 22 characters, corresponding to IFC64. – Dominique Jul 28 '23 at 09:06
  • 1
    https://github.com/hakonhc/IfcGuid/blob/master/IfcGuid/IfcGuid.cs was pretty easy to find. – Retired Ninja Jul 28 '23 at 09:06
  • @RetiredNinja Well, I am not saying "that's garbage" - it _may_ be completely ok. But the stats and surroundings do not indicate that to be a stable, well-documented, "production-ready" product. – Fildor Jul 28 '23 at 09:09
  • 1
    @RetiredNinja: if you don't make my mistake, adding the 64 to the "IFC" string as an exact match :-) Thanks a lot for your answer, by the way. – Dominique Jul 28 '23 at 09:09
  • @Fildor-standswithMods: pardon my ignorance about GitHub, but how can I judge the stability and quality of a Github product? – Dominique Jul 28 '23 at 09:11
  • 2
    [this](https://technical.buildingsmart.org/resources/ifcimplementationguidance/ifc-guid/) suggest that an IFC GUID is a special Base64 encoding of a 128bit guid. Since each character is 6 bits it has to use 22 characters, with some bits left over, but these bits are not used. I.e. you need to find or make a method to encode & decode such a string to a conventional 128-bit GUID. – JonasH Jul 28 '23 at 09:11
  • 1
    The problem with IFC64 is there are almost no results and none are a specification which makes me think it might be a misunderstanding. – Retired Ninja Jul 28 '23 at 09:12
  • 1
    _"how can I judge the stability and quality of a Github product?"_ - Well, that's kind of opinionated. But _I_ mostly look for how good the documentation is, if it's widely used. If it's maintained regularly, ... maybe I know the author ... what License it uses, ... if it _works_ haha ... erm yeah. It may be difficult to judge if it is something _that_ nieshy. The _least_ thing I expect is a README.md ... – Fildor Jul 28 '23 at 09:15
  • 1
    @Dominique the only way to properly judge the quality and stability of an external library is to test it. Do not believe opinions. Even the most commonly used libs have critical bugs all the time (yes, I'm looking at you openssl). – freakish Jul 28 '23 at 09:15
  • ^^ And also not "Stars" – Fildor Jul 28 '23 at 09:16
  • ^^ In the company, we tend to have specific unit/integration tests for community-driven libs (and some commercial ones ;) ) to ensure they behave as _we expect_ (in contrast to as they are documented to do). – Fildor Jul 28 '23 at 09:46
  • @RetiredNinja: I have still not understood what "IFC" stands for, but you do have a valid point: are you aware of any specification, defining the IFC64 GUID? – Dominique Jul 28 '23 at 09:55
  • 1
    "IFC" = "Industry Foundation Classes" => https://technical.buildingsmart.org/standards/ – Fildor Jul 28 '23 at 10:01
  • 1
    This page sound a good clue [IFC GUID](https://technical.buildingsmart.org/resources/ifcimplementationguidance/ifc-guid/). At the bottom, it expose implementation example in python and csharp. – vernou Jul 28 '23 at 10:12
  • 3
    @Dominique btw, why don't you ask the customer for details? – freakish Jul 28 '23 at 10:50

1 Answers1

1

The IFC GUIDs are 128 bit long (not 132 bit!), same as other UUIDs. When represented in text, IFC GUIDs are encoded using radix 64 and a 64-character alphabet (see below). This is used similar to the standard hexadecimal representation, but omits the dashes and uses a larger base, such that it is more compact than hexadecimal representation.

Note that contrary to the Base64 encoding method for arbitrary binary data to text aligned left and with right-side padding, the IFC radix 64 encoding is producing a base 64 number aligned right with left-side padding. Thus, since every digit is 6 bits and 128 has a reminder of 2 when divided by 6, the first (most significant) digit is always 0, 1, 2 or 3.

Here is some C# code to illustrate:

String charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$";
var hexUuid = Guid.NewGuid().ToString().Replace("-", "");
Console.WriteLine("Hex: " + hexUuid);
var numUuid = BigInteger.Parse("0" + hexUuid, NumberStyles.AllowHexSpecifier);
Console.WriteLine("Dec: " + numUuid);
var ifcUuid = Enumerable.Range(0,22).Select(i => charset[(int)((numUuid >> (i*6)) & 63)]).Reverse(); 
Console.WriteLine("IFC: " + string.Join("", ifcUuid));
hlg
  • 1,321
  • 13
  • 29