How can SystemInfo.deviceUniqueIdentifier be unique? - unity3d

According to http://docs.unity3d.com/ScriptReference/SystemInfo-deviceUniqueIdentifier.html, SystemInfo.deviceUniqueIdentifier
It is guaranteed to be unique for every device (Read Only).
If you delete and reinstall your application, this value will change. How can it guarantee that there isn't another iPhone in the world that happened to generate the same identifier?
(I know that the identifier is pretty long so it is quite unlikely for this to happen - but I'd like to know why)

As the description says, it's typically some form of device ID, set by the vendor:
iOS: on pre-iOS7 devices it will return hash of MAC address. On iOS7
devices it will be UIDevice identifierForVendor or, if that fails for
any reason, ASIdentifierManager advertisingIdentifier.
Windows Store
Apps: uses AdvertisingManager::AdvertisingId for returning unique
device identifier, if option in 'PC Settings -> Privacy -> Let apps
use my advertising ID for experiences across apps (turning this off
will reset your ID)' is disabled, Unity will fallback to
HardwareIdentification::GetPackageSpecificToken().Id.
Even if these values were random, they come out in the same format as a GUID with 32 hexadecimal characters (128bits). The number of possibilities is rather large.
From Wikipedia:
The total number of unique such GUIDs is 2^122 (approximately 5.3×10^36). This number is so large that the probability of the same number being
generated randomly twice is negligible; however other GUID versions
have different uniqueness properties and probabilities, ranging from
guaranteed uniqueness to likely duplicates. Assuming uniform
probability for simplicity, the probability of one duplicate would be
about 50% if every person on earth as of 2014 owned 600 million GUIDs.

Related

Is the Web MIDI API Port ID unique to each device or the device in general?

Referring to https://webaudio.github.io/web-midi-api/#dom-midiport-id.
As an example, let's say we're talking about Synth X.
The name and manufacturer parameters of the MIDIPort would be the same across any instance of Synth X that connects.
My question is, would each individual Synth X product have a unique id parameter?
For example, my friend and I both have Synth X, would the IDs be unique?
Or is this more like a device ID? Like manufacture + name = ID? All Synth X products would return the same ID?
No, it isn't unique.
At least on Windows, these port numbers/IDs are just the enumeration order of devices. While the idea of the spec is that you can save one and re-open the same device later, this doesn't really work in between page loads in practice. (Which, is really unfortunate!)
Taking this another step further, the OS doesn't really know how to uniquely identify the device either. Even in the case of USB, the device descriptor doesn't always have a unique ID. It's common for cheaper devices to all be programmed with the same serial, or no serial at all.

iBeacons: understanding minor, major and UUID

I can't seem to figure out the relevance or importance of major and minor values in detecting iBeacons. When I register and configure my Gimbal beacon, I give it a specific set of values for UUID, major and minor, and then when I use my cordova iBeacon plugin I can detect my beacons but only if I instruct it to look for these exact parameters.
It would seem to me that only the uuid would be critical to detecting beacons. Yet they aren't detected by my app unless I match value for value each of those 3 criteria
Can anyone elucidate the relevance of the major and minor values in beacon detection and is it true that my code needs to specifically instruct the plugin to look for beacons matching all these values.
Hope this post makes sense... the iBeacon detection has so many moving parts that learning about it has tied my brain in a pretzel
The iBeacon protocol was implemented this way to ensure that each beacon would be unique. If you have a large beacon deployment (lets say in all of your stores across the country) Then you want to set the identifiers in such a way that you can id the beacons individually. An example deployment would look like this:
All beacon UUIDS: 1234...
All department stores in Boston: Major = 1
All department stores in Chicago: Major = 2
Minor can vary by aisle or section.
So then I know if I detect beacon UUID 1234..., Major 1 Minor 8 I can map it to the Boston store clothing section. This is just an example (and a kind of lame on at that) but essentially the levels of identifiers are just a greater insurance that the beacon you detect is the one you actually want.
When monitoring for iBeacons you can actually monitor at each of the different identifier levels, so you could monitor for all beacons with a UUID, all beacons with a UUID and Major, or all beacons with a UUID, Major, and Minor (which ideally would just be a single beacon)
This statement is critical:
It would seem to me that only the uuid would be critical to detecting beacons. Yet they aren't detected by my app unless I match value for value each of those 3 criteria
Using raw iOS APIs and the Android Beacon Library, supplying only the UUID will match beacons. You do not need to specify the major and minor to detect beacons. The fact that you are seeing otherwise means something is wrong with the code you are running, the framework it is using, or both.
The purpose of the major and minor are to subdivide the identifier space for logical purposes. If you then match solely on UUID or UUID and major, you can take diffrent actions depending on which beacon is detected by examining the minor value.

Is it possible to declare one's own [mini] namespace within an NSUUID?

The Wikipedia page https://en.wikipedia.org/wiki/Universally_unique_identifier states that in version 3 (and therefore presumably 5) of the UUID spec: "Six bits are replaced by fixed values"
I am working on an iPhone app that utilises the NSUUID class. My client has asked for the ability to declare his own small fixed set of chars within the full UUID string. From what I have read thus far, I don't think this is possible - for just loads for understandable reasons - however I am obliged to ask whether there is a way, so that I can answer/deflect his questions with surety.
So is there or not, please?
Thanks in advance.
Is it possible? Of course; but unless your client's iPhone app lives in an alternate universe, perhaps your client's iPhone app would be better served by sticking to the versions described by the RFC 4122 variant.
It might be helpful to sit down with your client and explain the uuid layout. You might consider using Mahonri Moriancumer's UUID and GUID Generator and Forensics to demonstrate UUID options.
Update: In thinking this through a bit more, there is a way to add a signature to generated UUIDs...
Consider the version 1 UUID structure (RFC 4122 variant). For this type of UUID, the last 12 digits represent the MAC address of the computer's ethernet card that generated the UUID.
If you were to get the MAC address from a specific ethernet card (even an old, obsolete one), and then destroy the card, you could be assured that no other computer will ever generate a UUID (v1) using that ethernet card's MAC address ever again. Then you could use that MAC address as your "own small fixed set of chars within the full UUID string".
Then, just write your own UUID v1 generator that uses this mac address as the last 12 digits of the UUID. The rest of the UUID digits could comply with the v1 spec. The resulting generated UUIDs would be fully complient with the v1 spec, and could be identified (as a set) by the last 12 digits.

Are NSManagedObject objectIDs unique across space and time like a CFUUID?

The NSManagedObjectID documentation states:
An NSManagedObjectID object is a compact, universal, identifier for a managed object. This forms the basis for uniquing in the Core Data Framework. A managed object ID uniquely identifies the same managed object both between managed object contexts in a single application, and in multiple applications (as in distributed systems).
Translation in my head: "There is probably no way that any two NSManagedObjectIDs are ever the same across the set of all instances of my application."
The CFUUID documentation states:
UUIDs ... are 128-bit values
guaranteed to be unique. A UUID is
made unique over both space and time
by combining a value unique to the
computer on which it was
generated—usually the Ethernet
hardware address—and a value
representing the number of
100-nanosecond intervals since October
15, 1582 at 00:00:00.
Translation in my head: "There is definitely no way that any two CFUUIDs are ever the same across the set of all instances of my application."
The fact that NSManagedObjectIDs are described as a "universal identifier" makes me almost certain that they offer the same uniqueness as a CFUUID, whereas "unique across space and time" leaves absolutely no room for doubt. Can anybody with more Core Data experience than me confirm or deny my thoughts?
Beyond uniqueness, there is one case where the object ID will change, and that's if you query it before persisting the object to disk. After saving, it will have a different ID. Beyond that point, the ID will not change. I just wanted to point this out because it caused me a bit of confusion until I figured out what was happening.
I can't comment on the hashing used to generate the NSManagedObjectID, but it does seem like the odds of it matching another NSManagedObject are vanishingly small, based on looking at the IDs generated.

How can I generate a unique, small, random, and user-friendly key?

A few months back I was tasked with implementing a unique and random code for our web application. The code would have to be user friendly and as small as possible, but still be essentially random (so users couldn't easily predict the next code in the sequence).
It ended up generating values that looked something like this:
Af3nT5Xf2
Unfortunately, I was never satisfied with the implementation. Guid's were out of the question, they were simply too big and difficult for users to type in. I was hoping for something more along the lines of 4 or 5 characters/digits, but our particular implementation would generate noticeably patterned sequences if we encoded to less than 9 characters.
Here's what we ended up doing:
We pulled a unique sequential 32bit id from the database. We then inserted it into the center bits of a 64bit RANDOM integer. We created a lookup table of easily typed and recognized characters (A-Z, a-z, 2-9 skipping easily confused characters such as L,l,1,O,0, etc.). Finally, we used that lookup table to base-54 encode the 64-bit integer. The high bits were random, the low bits were random, but the center bits were sequential.
The final result was a code that was much smaller than a guid and looked random, even though it absolutely wasn't.
I was never satisfied with this particular implementation. What would you guys have done?
Here's how I would do it.
I'd obtain a list of common English words with usage frequency and some grammatical information (like is it a noun or a verb?). I think you can look around the intertubes for some copy. Firefox is open-source and it has a spellchecker... so it must be obtainable somehow.
Then I'd run a filter on it so obscure words are removed and that words which are too long are excluded.
Then my generation algorithm would pick 2 words from the list and concatenate them and add a random 3 digits number.
I can also randomize word selection pattern between verb/nouns like
eatCake778
pickBasket524
rideFlyer113
etc..
the case needn't be camel casing, you can randomize that as well. You can also randomize the placement of the number and the verb/noun.
And since that's a lot of randomizing, Jeff's The Danger of Naïveté is a must-read. Also make sure to study dictionary attacks well in advance.
And after I'd implemented it, I'd run a test to make sure that my algorithms should never collide. If the collision rate was high, then I'd play with the parameters (amount of nouns used, amount of verbs used, length of random number, total number of words, different kinds of casings etc.)
In .NET you can use the RNGCryptoServiceProvider method GetBytes() which will "fill an array of bytes with a cryptographically strong sequence of random values" (from ms documentation).
byte[] randomBytes = new byte[4];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);
You can increase the lengh of the byte array and pluck out the character values you want to allow.
In C#, I have used the 'System.IO.Path.GetRandomFileName() : String' method... but I was generating salt for debug file names. This method returns stuff that looks like your first example, except with a random '.xyz' file extension too.
If you're in .NET and just want a simpler (but not 'nicer' looking) solution, I would say this is it... you could remove the random file extension if you like.
At the time of this writing, this question's title is:
How can I generate a unique, small, random, and user-friendly key?
To that, I should note that it's not possible in general to create a random value that's also unique, at least if each random value is generated independently of any other. In addition, there are many things you should ask yourself if you want to generate unique identifiers (which come from my section on unique random identifiers):
Can the application easily check identifiers for uniqueness within the desired scope and range (e.g., check whether a file or database record with that identifier already exists)?
Can the application tolerate the risk of generating the same identifier for different resources?
Do identifiers have to be hard to guess, be simply "random-looking", or be neither?
Do identifiers have to be typed in or otherwise relayed by end users?
Is the resource an identifier identifies available to anyone who knows that identifier (even without being logged in or authorized in some way)?
Do identifiers have to be memorable?
In your case, you have several conflicting goals: You want identifiers that are—
unique,
easy to type by end users (including small), and
hard to guess (including random).
Important points you don't mention in the question include:
How will the key be used?
Are other users allowed to access the resource identified by the key, whenever they know the key? If not, then additional access control or a longer key length will be necessary.
Can your application tolerate the risk of duplicate keys? If so, then the keys can be completely randomly generated (such as by a cryptographic RNG). If not, then your goal will be harder to achieve, especially for keys intended for security purposes.
Note that I don't go into the issue of formatting a unique value into a "user-friendly key". There are many ways to do so, and they all come down to mapping unique values one-to-one with "user-friendly keys" — if the input value was unique, the "user-friendly key" will likewise be unique.
If by user friendly, you mean that a user could type the answer in then I think you would want to look in a different direction. I've seen and done implementations for initial random passwords that pick random words and numbers as an easier and less error prone string.
If though you're looking for a way to encode a random code in the URL string which is an issue I've dealt with for awhile then I what I have done is use 64-bit encoded GUIDs.
You could load your list of words as chakrit suggested into a data table or xml file with a unique sequential key. When getting your random word, use a random number generator to determine what words to fetch by their key. If you concatenate 2 of them, I don't think you need to include the numbers in the string unless "true randomness" is part of the goal.