[Hardhats] GUID/UUID in MUMPS

138 views
Skip to first unread message

Richard Braman - EHR Doctors

unread,
May 19, 2010, 9:11:14 AM5/19/10
to Hardhats
Bhaskar,

Do you have any code that will create a GUID or UUID in MUMPS running
on GT.M?

Is there any method in Cache for doing the same?

Richard

--
http://groups.google.com/group/Hardhats
To unsubscribe, send email to Hardhats+u...@googlegroups.com

JohnLeo Zimmer

unread,
May 19, 2010, 9:55:52 AM5/19/10
to hard...@googlegroups.com
GTM> zsystem "uuidgen"
1cf62d3b-4792-474d-98eb-e858317ce63a

I think there a number of places in VistA where this might be useful.
e.g. PATIENT, NEW PERSON, INSTITUTION

JL.Z
--

"You can see a lot, just by looking." - Yogi Berra

Ben Mehling

unread,
May 19, 2010, 9:59:23 AM5/19/10
to hard...@googlegroups.com
On Wed, May 19, 2010 at 6:55 AM, JohnLeo Zimmer <johnl...@gmail.com> wrote:
> GTM> zsystem "uuidgen"
> 1cf62d3b-4792-474d-98eb-e858317ce63a

Just a note -- as previously discussed, anything that calls a GT.M or
Cache specific method should be appropriately wrapped to abstract the
platform.

- Ben

JohnLeo Zimmer

unread,
May 19, 2010, 11:15:09 AM5/19/10
to hard...@googlegroups.com
Ben is correct, Needs to be in a routine that can check for M version (cache/gtm) and OS (cacheWin/cacheLinux). I'd use pipes. See the work on robust hashing for platform independent code examples.


In GT.M

OPEN "PIPE":(COMMAND="uuidgen")::"PIPE"
USE "PIPE" READ UUID

in Cache' this works on Linux version...

OPEN "uuidgen":"Q"
USE "uuidgen" READ UUID

Need to find a Windows call equivalent to uuidgen for:

OPEN "some_sortof_windows_uuid.exe":"Q"

jl.z


On Wed, May 19, 2010 at 8:59 AM, Ben Mehling <ben.m...@medsphere.com> wrote:
>
> On Wed, May 19, 2010 at 6:55 AM, JohnLeo Zimmer <johnl...@gmail.com> wrote:
> > GTM> zsystem "uuidgen"
> > 1cf62d3b-4792-474d-98eb-e858317ce63a
>
> Just a note -- as previously discussed, anything that calls a GT.M or
> Cache specific method should be appropriately wrapped to abstract the
> platform.
>


--

"You can see a lot, just by looking." - Yogi Berra

K.S. Bhaskar

unread,
May 19, 2010, 11:17:20 AM5/19/10
to hard...@googlegroups.com
The only difference between a UUID and a 16-byte random number is the added formatting.  If you want to get UUID in large volumes, just call out to standard library function or read /dev/random or /dev/urandom.  [Caution, /dev/random on Linux is a true random number, and you can suck all the entropy out of a system unless you provide an entropy source such as an Entropy Key.]

Since it is unlikely that VistA needs UUIDs in large quantities, my suggestion is simply to read from /proc/sys/kernel/random/uuid:

GTM>set uuid="/proc/sys/kernel/random/uuid"                  

GTM>for i=1:1:3 open uuid:readonly use uuid read x use $principal close uuid write x,!
446943e2-2349-4ffb-9944-087334f06642
f117d430-ce59-41e5-b1d0-fde4f5ad208f
13c68c57-903c-41d1-b296-a7c6323594ef

GTM>


Note that you have to open and close it each time you need a UUID.  The beauty of this approach is that VistA provides a way to package IO devices so that they can be presented to applications in a portable way across MUMPS implementations.

Also of interest is /proc/sys/kernel/random/boot_id - every time Linux boots, it puts a new UUID and this provides a convenient way to identify "sessions".

-- Bhaskar
GT.M - Rock solid. Lightning fast. Secure. No compromises.
_____________

The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.
_____________

JohnLeo Zimmer

unread,
May 19, 2010, 11:36:11 AM5/19/10
to hard...@googlegroups.com
Ah! Google:
"The uuidgen utility (Uuidgen.exe) is automatically installed when you install the Platform Software Development Kit (SDK)"

So, with that dependency met, the cache version would be the same on Windows or Linux.

rtweed

unread,
May 19, 2010, 11:53:41 AM5/19/10
to Hardhats
Bhaskar

Just as a matter of interest, is this approach significantly faster
than a Mumps code loop that calls $r 31 times and constructs a UUID
string from the results?

Rob

On 19 May, 16:17, "K.S. Bhaskar" <ks.bhas...@fisglobal.com> wrote:
> The only difference between a UUID and a 16-byte random number is the added formatting.  If you want to get UUID in large volumes, just call out to standard library function or read /dev/random or /dev/urandom.  [Caution, /dev/random on Linux is a true random number, and you can suck all the entropy out of a system unless you provide an entropy source such as an Entropy Key.]
> Since it is unlikely that VistA needs UUIDs in large quantities, my suggestion is simply to read from /proc/sys/kernel/random/uuid:GTM>set uuid="/proc/sys/kernel/random/uuid"                  
> GTM>for i=1:1:3 open uuid:readonly use uuid read x use $principal close uuid write x,!
> 446943e2-2349-4ffb-9944-087334f06642
> f117d430-ce59-41e5-b1d0-fde4f5ad208f
> 13c68c57-903c-41d1-b296-a7c6323594ef
> GTM>
> Note that you have to open and close it each time you need a UUID.  The beauty of this approach is that VistA provides a way to package IO devices so that they can be presented to applications in a portable way across MUMPS implementations.
> Also of interest is /proc/sys/kernel/random/boot_id - every time Linux boots, it puts a new UUID and this provides a convenient way to identify "sessions".
> -- BhaskarGT.M - Rock solid. Lightning fast. Secure. No compromises.
> On 05/19/2010 09:59 AM, Ben Mehling wrote:
>
> On Wed, May 19, 2010 at 6:55 AM, JohnLeo Zimmer<johnl...@gmail.com>wrote:
> > GTM> zsystem "uuidgen"
> > 1cf62d3b-4792-474d-98eb-e858317ce63a
> Just a note -- as previously discussed, anything that calls a GT.M or
> Cache specific method should be appropriately wrapped to abstract the
> platform.
> - Ben
> --http://groups.google.com/group/Hardhats
> To unsubscribe, send email toHardhats+...@googlegroups.com
>
> _____________
> The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.
> _____________
>
>
>
>
>
> --http://groups.google.com/group/Hardhats

Bhaskar, KS

unread,
May 19, 2010, 12:02:52 PM5/19/10
to hard...@googlegroups.com

Although I have not benchmarked it, calling $r is likely to be faster.  But people interested in UUIDs may require a higher quality of randomness than the GT.M pseudo-random number generator behind $r.

Regards
-- Bhaskar
--------------------------
Sent from my BlackBerry Wireless Handheld

Ben Mehling

unread,
May 19, 2010, 12:55:48 PM5/19/10
to hard...@googlegroups.com
On Wed, May 19, 2010 at 8:15 AM, JohnLeo Zimmer <johnl...@gmail.com> wrote:
> Ben is correct, Needs to be in a routine that can check for M version
> (cache/gtm) and OS (cacheWin/cacheLinux). I'd use pipes. See the work on
> robust hashing for platform independent code examples.

VistA-derivatives have a "platform setup" function built in
(ZTMGRSET). I think it would be best to use that facility, rather
than do platform detection in each and every location you want to use
something like this...

I think we've discussed this concept on this list previously. A
utility routine should be created for things like encryption, uuid
gen, etc. and added to the GT.M and Cache progenitor files. Then
general routines would have access to these standard services and
wouldn't care what platform they were on.

- Ben

Richard Braman - EHR Doctors

unread,
May 19, 2010, 3:05:08 PM5/19/10
to Hardhats
Thanks All.

I think you can download a small guid generation utility for Windows
from MS here:
http://www.microsoft.com/downloads/details.aspx?familyid=94551f58-484f-4a8c-bb39-adb270833afc&displaylang=en

so you could run

OPEN "GUIDGen.EXE":"Q"

like JohnLeo suggested

Rich


On May 19, 12:55 pm, Ben Mehling <ben.mehl...@medsphere.com> wrote:
> On Wed, May 19, 2010 at 8:15 AM, JohnLeo Zimmer <johnleo...@gmail.com> wrote:
> > Ben is correct, Needs to be in a routine that can check for M version
> > (cache/gtm) and OS (cacheWin/cacheLinux). I'd use pipes. See the work on
> > robust hashing for platform independent code examples.
>
> VistA-derivatives have a "platform setup" function built in
> (ZTMGRSET).  I think it would be best to use that facility, rather
> than do platform detection in each and every location you want to use
> something like this...
>
> I think we've discussed this concept on this list previously.  A
> utility routine should be created for things like encryption, uuid
> gen, etc. and added to the GT.M and Cache progenitor files.  Then
> general routines would have access to these standard services and
> wouldn't care what platform they were on.
>
> - Ben
>
> --http://groups.google.com/group/Hardhats

r...@rcresearch.us

unread,
May 19, 2010, 3:08:07 PM5/19/10
to hard...@googlegroups.com
Just for grins, I tried building this tool. It is pretty straight
forward. The optional argument will allow for the creation of much larger
UUIDs. The argument is the integer size of the UUID. If the call is made
by name, it returns the larger UUID in that argument. So, here is a test
run;

>W $$^%GETUUID()
80ce2f63-db1e-3030-19f7-d6d7874849a
>S A=12
>W $$^%GETUUID(.A)
8a776e26-542a---
>W A
81776e26542a
>S A=48 W $$^%GETUUID(.A)
34d1bfs4-5d42-a55f-f521-23e7bb5a35f8
>W A
34d1bfs45d42a55ff52123e7bb5a35f82eF4bc5e0153f14f

Code attached.
_GETUUID.m

glilly

unread,
May 19, 2010, 3:23:20 PM5/19/10
to Hardhats
Here's a routine that delivers a Version 4 UUID in Mumps (I think)

UUID() ; GENERATE A RANDOM UUID (Version 4)
N I,J,ZS
S ZS="0123456789abcdef" S J=""
F I=1:1:36 S J=J_$S((I=9)!(I=14)!(I=19)!(I=24):"-",I=15:4,I=20:"a",
1:$E(ZS,$R(15)+1))
Q J
;

and here's what the output looks like...

GTM>w $$UUID^C0CUTIL
2545ec68-9774-46ae-a16b-3e67e876d8d4
GTM>w $$UUID^C0CUTIL
bc732117-33cd-4500-aace-6aa96ab626de
GTM>w $$UUID^C0CUTIL
c051be05-cd31-41b9-ac6d-b9284807754d
GTM>w $$UUID^C0CUTIL
ccc568c9-c792-4237-a477-cc60c34a07d7

I followed the spec outlined here:
http://en.wikipedia.org/wiki/Universally_Unique_Identifier

gpl
> >> Zimmer<johnleo...@gmail.com>wrote:
>  _GETUUID.m
> < 1KViewDownload

glilly

unread,
May 19, 2010, 3:37:49 PM5/19/10
to Hardhats
Chris was right; it need to be $r(16)+1

UUID() ; GENERATE A RANDOM UUID (Version 4)
N I,J,ZS
S ZS="0123456789abcdef" S J=""
F I=1:1:36 S J=J_$S((I=9)!(I=14)!(I=19)!(I=24):"-",I=15:4,I=20:"a",
1:$E(ZS,$R(16)+1))
Q J
;

...thanks Chris

gpl

DanB

unread,
May 19, 2010, 4:23:40 PM5/19/10
to Hardhats
I thought GUIDs were generated using the MAC address of the system's
network card, thus (supposedly) "enforcing" the globally unique
function.

glilly

unread,
May 19, 2010, 4:34:24 PM5/19/10
to Hardhats
That was "version 1" of the spec. Version 4 supports "random" UUIDs

Version 1 (MAC address)
Conceptually, the original (version 1) generation scheme for UUIDs was
to concatenate the UUID version with the MAC address of the computer
that is generating the UUID, and with the number of 100-nanosecond
intervals since the adoption of the Gregorian calendar in the West. In
practice, the actual algorithm is more complicated. This scheme has
been criticized in that it is not sufficiently "opaque"; it reveals
both the identity of the computer that generated the UUID and the time
at which it did so.

Version 4 (random)
Version 4 UUIDs use a scheme relying only on random numbers. This
algorithm sets the version number as well as two reserved bits. All
other bits are set using a random or pseudorandom data source. Version
4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with any
hexadecimal digits for x but only one of 8, 9, A, or B for y. e.g.
f47ac10b-58cc-4372-a567-0e02b2c3d479.

http://en.wikipedia.org/wiki/Universally_Unique_Identifier



On May 19, 4:23 pm, DanB <b351...@yahoo.com> wrote:
> I thought GUIDs were generated using the MAC address of the system's
> network card, thus (supposedly) "enforcing" the globally unique
> function.
>
> --http://groups.google.com/group/Hardhats

JohnLeo Zimmer

unread,
May 19, 2010, 6:10:09 PM5/19/10
to hard...@googlegroups.com
I would suggest adding an entry point to ^%ZOSV
(ZOSVGUX for GT.M, ZOSVONT for Cache')...
so that this default construct:

>W $$UUID^%ZOSV() would return a random uuid, version 4.

It should also allow $$UUID^%ZOSV(type)where type could be "r" or "t" to produce the MAC_address/timestamp version, which I think could be useful for things like networks of VistA installations, patient ID, etc.

jl.z

“The average cow makes enough waste per day to power a 100-watt light bulb"
http://www.nytimes.com/2010/05/19/technology/19cows.html?ref=technology

--

"You can see a lot, just by looking." - Yogi Berra

Wally

unread,
May 20, 2010, 4:39:09 PM5/20/10
to Hardhats
I did it this way to reduce the number of calls to $R

UUID() ;
N R,I,J,N
S N="",R="" F S N=N_$R(100000) Q:$L(N)>64
F I=1:2:64 S R=R_$E("0123456789abcdef",($E(N,I,I+1)#16+1))
Q $E(R,1,8)_"-"_$E(R,9,12)_"-4"_$E(R,14,16)_"-"_$E("89ab",$E(N,
17)#4+1)_$E(R,18,20)_"-"_$E(R,21,32)

glilly

unread,
May 20, 2010, 5:26:31 PM5/20/10
to Hardhats
Nice. Thanks Wally!!!!!
gpl

On May 20, 4:39 pm, Wally <wally.f...@va.gov> wrote:
> I did it this way to reduce the number of calls to $R
>
> UUID()  ;
>         N R,I,J,N
>         S N="",R="" F  S N=N_$R(100000) Q:$L(N)>64
>         F I=1:2:64 S R=R_$E("0123456789abcdef",($E(N,I,I+1)#16+1))
>         Q $E(R,1,8)_"-"_$E(R,9,12)_"-4"_$E(R,14,16)_"-"_$E("89ab",$E(N,
> 17)#4+1)_$E(R,18,20)_"-"_$E(R,21,32)
>
> --http://groups.google.com/group/Hardhats

K.S. Bhaskar

unread,
May 20, 2010, 9:29:47 PM5/20/10
to hard...@googlegroups.com
Let me express my concerns about using $R() for generating UUIDs. I just
don't think that it provides the quality of randomness expected of UUIDs.
In addition to /proc/sys/kernel/random/uuid you can also use
/dev/urandom and /dev/random.

Other choices include openssl and gpg, e.g.:

$ openssl rand -hex 16
0f594a2a5290d47753b1a9d515bad427
$ gpg --gen-random 0 16 | od -t x1
0000000 5f 4f 2b a8 14 2e 53 2c aa bf 1f fb 92 c6 9d 15
0000020
$

With gpg, after --gen-random 0 represents low quality randomness, 2
represents crypto grade randomness and 1 is in-between. I would use at
least 1 for UUIDs, and preferably 2.

Regards
-- Bhaskar

GT.M - Rock solid. Lightning fast. Secure. No compromises.

_____________

The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.
_____________

Sam Habiel

unread,
Dec 6, 2018, 10:53:32 AM12/6/18
to Hardhats
Reviving an old thread...

I was writing code that needed this today; and I searched VistA to see if there was a an existing call. I found one; but it's currently unmaintained code from HMP. There is also one in Clinical Procedures that I think is currently used.

D GETGUID^MDCLIO1(.X)

--Sam

K.S. Bhaskar

unread,
Dec 6, 2018, 11:39:46 AM12/6/18
to Hardhats
My recommendation: open /dev/urandom (and leave it open for the lifetime of the process) and read as many bytes from it as you want. You won't lose entropy if you read more than you need.

Regards
– Bhaskar
Reply all
Reply to author
Forward
0 new messages