The CreatorCon Call for Content is officially open! Get started here.

How do I import the ObjectGuid from LDAP in a Hexadecimal format?

John VanBruggen
Giga Guru

I noticed that if you export these from AD they come out as Hex and when imported into SNOW they seem to be BASE64.

Example:  

On a file provided from AD administrator, the guid is as follows: 9e5bab01-07dc-4ba1-a88f-93342f4b0927

Yet that same group when imported into SNOW shows as: AatbntwHoUuoj5M0L0sJJw==

I have found 1 website that accurately converts these from one to the other.

Online GUID Conversion Tool To Convert Hex Base64 Int

Is there a way to convert   9e5bab01-07dc-4ba1-a88f-93342f4b0927 to AatbntwHoUuoj5M0L0sJJw==

Better yet, is there a way to force SNOW to import it in HEX to begin with instead of forcing it to BASE64?

Check out my Consultant's Survival Guide
https://youtube.com/watch?v=zYi8KhP9SUk
1 ACCEPTED SOLUTION

I found the following will prevent the field from being modified from the original guid in ldap.


http://wiki.servicenow.com/index.php?title=Available_System_Properties#gsc.tab=0


http://wiki.servicenow.com/index.php?title=Available_System_Properties#gsc.tab=0



glide.ldap.binary_attributes


Comma-separated list of LDAP attributes that should be converted from binary format to encoded64 strings. If you set this property, only the values listed are converted. The most common attributes are objectSID and objectGUID. These converted values are unique and can be used as the coalesce field on the LDAP import mapping. If this property is blank, ServiceNow tries to map these binary attributes without the conversion and they are not guaranteed to be unique since they are not properly converted to string values. You can set this property for a MID Server to import BLOB data through a MID Server, starting with the Fuji release.
Check out my Consultant's Survival Guide
https://youtube.com/watch?v=zYi8KhP9SUk

View solution in original post

18 REPLIES 18

jonnygrove
Mega Guru

I had the same requirement and came up with this solution, building on Javascript that I found from another site to convert the GUID in all it's initial forms.

I added the following Script Include so I could easily call the script from anywhere in the platform.

var guidUtils = Class.create();
guidUtils.prototype = {
	initialize: function() {
	},
	base64ToGuid: function (str){
		var decoded = GlideStringUtil.base64DecodeAsBytes(str);
		var n = decoded.length;

		if (n<16){
			return '';
		}

		var retVal = '';
		retVal = retVal + this.prefixZeros(decoded[3] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[2] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[1] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[0] & 0xFF).toUpperCase();
		retVal = retVal +'-';
		retVal = retVal + this.prefixZeros(decoded[5] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[4] & 0xFF).toUpperCase();
		retVal = retVal +'-';
		retVal = retVal + this.prefixZeros(decoded[7] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[6] & 0xFF).toUpperCase();
		retVal = retVal +'-';
		retVal = retVal + this.prefixZeros(decoded[8] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[9] & 0xFF).toUpperCase();
		retVal = retVal +'-';
		retVal = retVal + this.prefixZeros(decoded[10] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[11] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[12] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[13] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[14] & 0xFF).toUpperCase();
		retVal = retVal + this.prefixZeros(decoded[15] & 0xFF).toUpperCase();
		retVal = '{'+retVal + '}';
		return retVal;
	},
	prefixZeros: function (value) {
		if (value <= 0xF) {
			return '0'+value.toString(16);
		} else {
			return value.toString(16);
		}
	},
	GUIDtoHex: function(guid) { 
		var str = guid;
		j=1;
		temp1="-";
		temp2="{";
		temp3="}";
		tmpGUID="";

		for (i=0;i<=str.length;i++)
		{
			t = (str.slice(i, j));
			if (t == temp1)
			{
				j = j + 1;
			}
			else if (t == temp2)
			{
				j = j + 1;
			}
			else if (t == temp3)
			{
				j = j + 1;
			}
			else 
			{
				j = j + 1;
				tmpGUID = tmpGUID + t;
			}
		}

		GuidStr = (tmpGUID.slice(6, 8));
		GuidStr = GuidStr + (tmpGUID.slice(4, 6));
		GuidStr = GuidStr + (tmpGUID.slice(2, 4));
		GuidStr = GuidStr + (tmpGUID.slice(0, 2));
		GuidStr = GuidStr + (tmpGUID.slice(10, 12));
		GuidStr = GuidStr + (tmpGUID.slice(8, 10));
		GuidStr = GuidStr + (tmpGUID.slice(14, 16));
		GuidStr = GuidStr + (tmpGUID.slice(12, 14));
		GuidStr = GuidStr + (tmpGUID.slice(16, 34));
		return GuidStr;
	},
	cone: function(hex)
	{
		var str = hex;
		GuidStr = (str.slice(6, 8));
		GuidStr = GuidStr + (str.slice(4, 6));
		GuidStr = GuidStr + (str.slice(2, 4));
		GuidStr = GuidStr + (str.slice(0, 2));
		GuidStr = GuidStr + (str.slice(10, 12));
		GuidStr = GuidStr + (str.slice(8, 10));
		GuidStr = GuidStr + (str.slice(14, 16));
		GuidStr = GuidStr + (str.slice(12, 14));

		GuidStr = GuidStr + (str.slice(16, 34));
		TempGuid = "{" + (GuidStr.slice(0, 8)) + "-" + (GuidStr.slice(8, 12)) + "-" + (GuidStr.slice(12, 16)) + "-" + (GuidStr.slice(16, 20)) + "-" + (GuidStr.slice(20, 34)) + "}";
		return TempGuid;
	},
	base64ToHex: function(base64) {
		var guidVal = this.base64ToGuid(base64);
		return this.GUIDtoHex(guidVal);
	},
	ldapQueryFormat:function(hex) {
		return '\\' + this._splitString(hex, 2).join('\\');
	},
	_splitString: function(str, n) {
		var ret = [];
		var i;
		var len;

		for(i = 0, len = str.length; i < len; i += n) {
			ret.push(str.substr(i, n));
		}
		return ret;
	},
	type: 'guidUtils'
};

There's a couple of functions you can call to convert the data based on what you need.

var helper = new guidUtils(); // Initialize the script
var GUIDOutput = helper.base64ToGuid('LY/xoAyrS0WLjcCFUpVwBw=='); // Output: {A0F18F2D-AB0C-454B-8B8D-C08552957007} Human Readable GUID Format found in AD
var cleanHexOutputFromGUID = helper.GUIDtoHex(GUIDOutput); // Output: 2D8FF1A00CAB4B458B8DC08552957007 Hex format
var cleanHexOutput = helper.base64ToHex('LY/xoAyrS0WLjcCFUpVwBw=='); // Output: 2D8FF1A00CAB4B458B8DC08552957007 Shortcut to Hex output directly from base64
var hexQueryOutput = helper.ldapQueryFormat(cleanHexOutput); // Output: \2D\8F\F1\A0\0C\AB\4B\45\8B\8D\C0\85\52\95\70\07 Will prepare a hex value for LDAP Queries

John Caruso
Kilo Guru

Code for converting to and from AD objectGuid (hex) string and base64 encoded string.

NOTE: Depends on GlideStringUtil methods available only in global scope. Create a global script include available to all scope to use in scoped app.

Updated 2020-11-02: Restructured to use alternate module pattern for global script includes shared with all scopes that avoids `java.lang.SecurityException: Invalid object in scoped script: [object Object]` when called from scoped app.

var objectGuidUtil = {};
(function (exports) {
    'use strict';

    // Variant 2 UUID encoding
    // https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding
    var encoding = [3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-', 8, 9, '-', 10, 11, 12, 13, 14, 15];

    function uint8(value) {
        return value & 0xff;
    }

    function int8(value) {
        var ref = uint8(value);
        return ref > 0x7f ? ref - 0x100 : ref;
    }

    function byteToHex(b) {
        var hex = uint8(b).toString(16);
        return hex.length < 2 ? '0' + hex : hex;
    }

    function hexToByte(str) {
        return int8(parseInt(str, 16));
    }

    function base64ToGuid(str) {
        var bytes = GlideStringUtil.base64DecodeAsBytes(str);

        if (bytes.length !== 16) {
            throw new Error('Base64 encoded string must decode to 16 bytes.');
        }

        var hexArr = bytes.map(byteToHex);

        return encoding.reduce(function (s, i) {
            return s + (i === '-' ? i : hexArr[i]);
        }, '');
    }

    function guidToBase64(str) {
        try {
            str = str.replace(/-/g, '');

            var hexArr = encoding.reduce(function (arr, i) {
                if (i === '-') return arr;
                arr.push(str.substr(i * 2, 2));
                return arr;
            }, []);

            var bytes = hexArr.map(hexToByte);

            return String(GlideStringUtil.base64Encode(bytes));
        } catch (e) {
            gs.error('guidToBase64: ' + e);
        }
    }

    exports.base64ToGuid = base64ToGuid;
    exports.guidToBase64 = guidToBase64;
})(objectGuidUtil);

I'll add that my usage of your code was to transform a value coming from SQL stored proc in Sailpoint: 

var hexGUID = "{dc5db0b9-d9c8-4ec9-b5cb-e5e21b81d4c1}";
var answer = objectGuidUtil.guidToBase64(hexGUID.slice(1,-1)); // String.slice(), to remove the curly brackets

That is, when your code goes into a script include, there's no "new()" initializer for using it. Thanks so much, this was an awesome find for an issue that is a very cloudy issue when researched all around the web!

Glad you found it useful! And thanks for including a usage example. I should have included one.