├── IfcGuid.sln ├── IfcGuid ├── IfcGuid.cs ├── IfcGuid.csproj ├── Program.cs └── Properties │ └── AssemblyInfo.cs └── Test ├── Properties └── AssemblyInfo.cs ├── Test.csproj └── UnitTest1.cs /IfcGuid.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IfcGuid", "IfcGuid\IfcGuid.csproj", "{EDB991EE-D805-4718-BDDE-6D9C56C9F608}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{67F1408C-0439-4F90-9ED3-61A1D2076886}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {EDB991EE-D805-4718-BDDE-6D9C56C9F608}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {EDB991EE-D805-4718-BDDE-6D9C56C9F608}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {EDB991EE-D805-4718-BDDE-6D9C56C9F608}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {EDB991EE-D805-4718-BDDE-6D9C56C9F608}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {67F1408C-0439-4F90-9ED3-61A1D2076886}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {67F1408C-0439-4F90-9ED3-61A1D2076886}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {67F1408C-0439-4F90-9ED3-61A1D2076886}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {67F1408C-0439-4F90-9ED3-61A1D2076886}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /IfcGuid/IfcGuid.cs: -------------------------------------------------------------------------------- 1 | namespace IfcGuid 2 | { 3 | using System; 4 | using System.Diagnostics; 5 | 6 | /// 7 | /// Conversion methods between an IFC 8 | /// encoded GUID string and a .NET GUID. 9 | /// This is a translation of the C code 10 | /// found here: http://www.iai-tech.org/ifc/IFC2x3/TC1/html/index.htm 11 | /// 12 | public static class IfcGuid 13 | { 14 | #region Static Fields 15 | 16 | /// 17 | /// The replacement table 18 | /// 19 | private static readonly char[] Base64Chars = 20 | { 21 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 22 | 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 23 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 24 | 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 25 | 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_', '$' 26 | }; 27 | 28 | #endregion 29 | 30 | #region Public Methods and Operators 31 | 32 | /// 33 | /// The reverse function to calculate the number from the characters 34 | /// 35 | /// 36 | /// The char array to convert from 37 | /// 38 | /// 39 | /// Position in array to start read 40 | /// 41 | /// 42 | /// The length to read 43 | /// 44 | /// 45 | /// The calculated nuber 46 | /// 47 | public static uint CvFrom64(char[] str, int start, int len) 48 | { 49 | int i; 50 | uint res = 0; 51 | 52 | Debug.Assert(len <= 4, "Length must be equal or lett than 4"); 53 | 54 | for (i = 0; i < len; i++) 55 | { 56 | int index = -1; 57 | int j; 58 | for (j = 0; j < 64; j++) 59 | { 60 | if (Base64Chars[j] == str[start + i]) 61 | { 62 | index = j; 63 | break; 64 | } 65 | } 66 | 67 | Debug.Assert(index >= 0, "Index is less than 0"); 68 | 69 | res = (res * 64) + ((uint)index); 70 | } 71 | 72 | return res; 73 | } 74 | 75 | /// 76 | /// Conversion of an integer into a characters with base 64 77 | /// using the table Base64Chars 78 | /// 79 | /// 80 | /// The number to convert 81 | /// 82 | /// 83 | /// The result char array to write to 84 | /// 85 | /// 86 | /// The position in the char array to start writing 87 | /// 88 | /// 89 | /// The length to write 90 | /// 91 | public static void CvTo64(uint number, ref char[] result, int start, int len) 92 | { 93 | int digit; 94 | 95 | Debug.Assert(len <= 4, "Length must be equal or lett than 4"); 96 | 97 | uint act = number; 98 | int digits = len; 99 | 100 | for (digit = 0; digit < digits; digit++) 101 | { 102 | result[start + len - digit - 1] = Base64Chars[(int)(act % 64)]; 103 | act /= 64; 104 | } 105 | 106 | Debug.Assert(act == 0, "Logic failed, act was not null: " + act); 107 | } 108 | 109 | /// 110 | /// Reconstruction of the GUID from an IFC GUID string (base64) 111 | /// 112 | /// 113 | /// The GUID string to convert. Must be 22 characters long 114 | /// 115 | /// 116 | /// GUID correspondig to the string 117 | /// 118 | public static Guid FromIfcGuid(string guid) 119 | { 120 | Debug.Assert(guid.Length == 22, "Input string must not be longer that 22 chars"); 121 | var num = new uint[6]; 122 | char[] str = guid.ToCharArray(); 123 | int n = 2, pos = 0, i; 124 | for (i = 0; i < 6; i++) 125 | { 126 | num[i] = CvFrom64(str, pos, n); 127 | pos += n; 128 | n = 4; 129 | } 130 | 131 | var a = (int)((num[0] * 16777216) + num[1]); 132 | var b = (short)(num[2] / 256); 133 | var c = (short)(((num[2] % 256) * 256) + (num[3] / 65536)); 134 | var d = new byte[8]; 135 | d[0] = Convert.ToByte((num[3] / 256) % 256); 136 | d[1] = Convert.ToByte(num[3] % 256); 137 | d[2] = Convert.ToByte(num[4] / 65536); 138 | d[3] = Convert.ToByte((num[4] / 256) % 256); 139 | d[4] = Convert.ToByte(num[4] % 256); 140 | d[5] = Convert.ToByte(num[5] / 65536); 141 | d[6] = Convert.ToByte((num[5] / 256) % 256); 142 | d[7] = Convert.ToByte(num[5] % 256); 143 | 144 | return new Guid(a, b, c, d); 145 | } 146 | 147 | /// 148 | /// Conversion of a GUID to a string representing the GUID 149 | /// 150 | /// 151 | /// The GUID to convert 152 | /// 153 | /// 154 | /// IFC (base64) encoded GUID string 155 | /// 156 | public static string ToIfcGuid(Guid guid) 157 | { 158 | var num = new uint[6]; 159 | var str = new char[22]; 160 | byte[] b = guid.ToByteArray(); 161 | 162 | // Creation of six 32 Bit integers from the components of the GUID structure 163 | num[0] = BitConverter.ToUInt32(b, 0) / 16777216; 164 | num[1] = BitConverter.ToUInt32(b, 0) % 16777216; 165 | num[2] = (uint)((BitConverter.ToUInt16(b, 4) * 256) + (BitConverter.ToUInt16(b, 6) / 256)); 166 | num[3] = (uint)(((BitConverter.ToUInt16(b, 6) % 256) * 65536) + (b[8] * 256) + b[9]); 167 | num[4] = (uint)((b[10] * 65536) + (b[11] * 256) + b[12]); 168 | num[5] = (uint)((b[13] * 65536) + (b[14] * 256) + b[15]); 169 | 170 | // Conversion of the numbers into a system using a base of 64 171 | int n = 2; 172 | int pos = 0; 173 | for (int i = 0; i < 6; i++) 174 | { 175 | CvTo64(num[i], ref str, pos, n); 176 | pos += n; 177 | n = 4; 178 | } 179 | 180 | return new string(str); 181 | } 182 | 183 | #endregion 184 | 185 | /* 186 | #region Extension Methods 187 | 188 | /// 189 | /// Get the Unique ID in encoded on IFC Format (base 64) 190 | /// 191 | /// 192 | /// 193 | public static string IfcGUID(this Autodesk.Revit.DB.Element element) 194 | { 195 | string a = element.UniqueId; 196 | Guid episodeId = new Guid(a.Substring(0, 36)); 197 | int elementId = int.Parse(a.Substring(37), NumberStyles.AllowHexSpecifier); 198 | int last_32_bits = int.Parse(a.Substring(28, 8), NumberStyles.AllowHexSpecifier); 199 | int xor = last_32_bits ^ elementId; 200 | a = a.Substring(0, 28) + xor.ToString("x8"); 201 | Guid guid = new Guid(a); 202 | return ToIfcGuid(guid); 203 | } 204 | #endregion 205 | */ 206 | } 207 | } -------------------------------------------------------------------------------- /IfcGuid/IfcGuid.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {EDB991EE-D805-4718-BDDE-6D9C56C9F608} 9 | Exe 10 | Properties 11 | IfcGuid 12 | IfcGuid 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | 19 | 3.5 20 | publish\ 21 | true 22 | Disk 23 | false 24 | Foreground 25 | 7 26 | Days 27 | false 28 | false 29 | true 30 | 0 31 | 1.0.0.%2a 32 | false 33 | false 34 | true 35 | 36 | 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | 45 | 46 | pdbonly 47 | true 48 | bin\Release\ 49 | TRACE 50 | prompt 51 | 4 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | False 64 | .NET Framework 3.5 SP1 Client Profile 65 | false 66 | 67 | 68 | False 69 | .NET Framework 3.5 SP1 70 | true 71 | 72 | 73 | 74 | 81 | -------------------------------------------------------------------------------- /IfcGuid/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace IfcGuid 4 | { 5 | /// 6 | /// Test program 7 | /// 8 | public class Program 9 | { 10 | static void Main( string[] args ) 11 | { 12 | Guid a = Guid.NewGuid(); 13 | Console.WriteLine(".NET GUID: " + a.ToString()); 14 | string ifc_guid = IfcGuid.ToIfcGuid( a ); 15 | Console.WriteLine("IFC GUID: " + ifc_guid); 16 | Guid b = IfcGuid.FromIfcGuid( ifc_guid ); 17 | Console.WriteLine("Back to .NET GUID: " + b.ToString()); 18 | System.Diagnostics.Debug.Assert(a == b, "GUID does not match"); 19 | Console.ReadKey(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /IfcGuid/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("IfcGuid")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("IfcGuid")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("d2c9a9a0-85c0-4fcf-ae49-c8bd1b3d481b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("Test")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b36ec9d7-0957-43a1-917f-9326da28c54e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Test/Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {67F1408C-0439-4F90-9ED3-61A1D2076886} 7 | Library 8 | Properties 9 | Test 10 | Test 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {EDB991EE-D805-4718-BDDE-6D9C56C9F608} 59 | IfcGuid 60 | 61 | 62 | 63 | 64 | 65 | 66 | False 67 | 68 | 69 | False 70 | 71 | 72 | False 73 | 74 | 75 | False 76 | 77 | 78 | 79 | 80 | 81 | 82 | 89 | -------------------------------------------------------------------------------- /Test/UnitTest1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace Test 5 | { 6 | using System.Diagnostics; 7 | 8 | using IfcGuid; 9 | 10 | [TestClass] 11 | public class UnitTest1 12 | { 13 | [TestMethod] 14 | public void TestMethod1() 15 | { 16 | var id = Guid.NewGuid(); 17 | var ifcGuid = IfcGuid.ToIfcGuid(id); 18 | var back = IfcGuid.FromIfcGuid(ifcGuid); 19 | Assert.AreEqual(back, id); 20 | Debug.WriteLine(ifcGuid, id.ToString()); 21 | } 22 | 23 | [TestMethod] 24 | public void IfcGuidTestCases() 25 | { 26 | string ifcguid = "01psB8wRl0Y00000000005"; 27 | Assert.AreEqual(ifcguid, IfcGuid.ToIfcGuid(IfcGuid.FromIfcGuid(ifcguid))); 28 | } 29 | 30 | [TestMethod] 31 | public void GuidTestCases() 32 | { 33 | string guid = "01cf62c8-e9bc-bf88-0000-000000000005"; 34 | var res = IfcGuid.FromIfcGuid(IfcGuid.ToIfcGuid(new Guid(guid))); 35 | Assert.AreEqual(guid, res.ToString()); 36 | } 37 | 38 | [TestMethod] 39 | public void TestCompare() 40 | { 41 | string guid = "01cf62c8-e9bc-bf88-0000-000000000005"; 42 | string ifcguid = "01psB8wRo$Y00000000005"; 43 | var convertedGuid = IfcGuid.ToIfcGuid(new Guid(guid)); 44 | Assert.AreEqual(convertedGuid, ifcguid); 45 | } 46 | } 47 | } 48 | --------------------------------------------------------------------------------