This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Reliable way of generating unique hardware ID
Am trying to generate an ID that will be unique to a particular computer. The ID will not be generated randomly. It will be calculation based, such that the ID generated for computer A will be fixed and unique to computer A. Everytime the program is executed on computer A, it will continue to generate the same ID and when executed on another computer, it will generate another ID unique to that computer. This is to ensure that two computers don't have the same ID.
My Challenge: For my program to be able to generate an ID unique to a computer, it needs to perform the calculation based on a seed unique to the computer executing it.
My Question: How can i get a value unique to a computer, so that i can use the value as a seed in the ID generation program?
Is it possible to get a value from a computer's hardware(eg motherboard) that is unique to that computer? That way, the value is most likely not to change as long as the computer's motherboard is not replaced.
MAC address? Thats (for practical purposes) unique to every NIC so it guarantee's reproducibility even if the user is dual booting. Sure there are rare cases of people trading cards, but coupled with other metrics (don't only use this, since network cards can be changed), it's still possible.
How would you get it?
public static byte[] getMACAddress() throws SocketException, UnknownHostException {
InetAddress address = InetAddress.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(address);
return networkInterface.getHardwareAddress();
}
If you want a String representation, do this
for (int byteIndex = 0; byteIndex < macAddress.length; byteIndex++) {
System.out.format("%02X%s", macAddress[byteIndex], (byteIndex < macAddress.length - 1) ? "-" : "");
}
(thanks to http://www.kodejava.org/examples/250.html)
Note: As mentioned in the comments, Mac addresses can be spoofed. But your talking about a small part of the population doing this, and unless your using this for anti-piracy stuff, its unique enough.
Win32 generates a computer SID, that is supposed to be unique for each installation that you can get via WMI or Active Directory, but that is pretty platform specific. You can also use the MAC address, as everyone else has mentioned, just make sure that it is a physical network adapter, as virtual adapters tend to share the same MAC address across computers.
However, UUID's (or GUID's) are 128 bit numbers that are supposed to be guaranteed unique, and were actually created for the purpose of solving the problem of generating unique identifiers across multiple, random machines. According to Wikipedia:
To put these numbers into perspective,
one's annual risk of being hit by a
meteorite is estimated to be one
chance in 17 billion,[25] that means
the probability is about 0.00000000006
(6 × 10−11), equivalent to the odds of
creating a few tens of trillions of
UUIDs in a year and having one
duplicate. In other words, only after
generating 1 billion UUIDs every
second for the next 100 years, the
probability of creating just one
duplicate would be about 50%. The
probability of one duplicate would be
about 50% if every person on earth
owns 600 million UUIDs.
The total number of possible combinations is 2^128 (or 3 x 10^38), so I tend to believe it. Also, most modern UUID generators don't use the V1 algorithm anymore (i.e. the one based off the MAC address), since it is considered a security issue due to the fact that one can tell when the GUID was generated, and who generated it. In the Win32 world, a security patch circa Win2K or NT 4 changed to use the V4 version of the algorithm, which is based off of a pseudo-random number instead of the MAC, and the JVM has always used the V3/V4 version.
EDIT: The method used to generate UUID's in Java is via the java.util.UUID class.
An easy way to do this is to read the ethernet hardware, or "mac" address.
http://download.oracle.com/javase/6/docs/api/java/net/NetworkInterface.html#getHardwareAddress()
Mac addresses are not quite as unique as people think, as they do get reused as time goes on. But the odds of one application or network having two identical ones are quite low.
The MAC address is unique enough for what you. See http://en.wikipedia.org/wiki/MAC_address
You didn't specify which language you are using. It may easier in some languages than others. Here is how to do it in Java http://www.kodejava.org/examples/250.html. Google around for your language.
Your best option is to base the ID on the MAC address of the primary network adaptor.
This is potentially likely to change at somepoint, but so is any single hard component.
FYI GUIDs are calculated using the MAC address.
Have you access to any information described in this article? Windows-only
http://msdn.microsoft.com/en-us/library/aa394587.aspx
Serial number, asset tag
Another option IFF you're using intel chips is the processor serial number, assuming you can ensure the feature is enabled. See Intel Serial # Note for more info
Related
I have this capstone project in which focuses on school attendance with the use of RFID Cards. In terms of security of the RFID , is there a way to identify if the card was cloned?
As far as I am aware, there is no reliable way to tell if a card is cloned, other than noticing 2 identical cards existing at the same time.
Due to the relatively large UID (Unique ID) size of PC/SC compliant smart-cards (usually 128 bits), the probability that your organisation buys 2 cards with the same UID is effectively zero. Therefore, if you see 2 scans of a card with the same UID at a similar time, but separated physically by a large distance, you can be sure that one of them has been cloned.
However, without using techniques such as this, as far as I know, there are no good ways to check this in a technical sense.
I wrote a class that, given a seed and difficulty, will return a playing field to my game. The generation is consistent (no matter what, the same seed & difficulty level will always result in the same play field). As far as I know all android devices use Java 1.6 so here goes my question(s):
Is it safe to send only the seed and difficulty to other devices in a multiplayer environment?
Do I need to worry about when Google updates Java version level form 1.6? or will they likely update all android devices to that version level (I am assuming the Random class will have been changed)? And if not what would be a good way to detect if Random class is different?
Rephrased, what precautionary measures should be in place to ensure that the class java.util.Random, which my field generation class uses heavily, will result in the same play field for every device? Or, alternatively, would it be more wise to consider sending all play field data to the non-hosting device(s)?
I could probably accomplish the latter with a reliable message with size of:
byte[ROWS * COLUMNS]
In advance, I appreciate any guidance/suggestions in this matter. This is a difficult issue to search for so some links for future views may be appropriate.
There are a few options here, but I guess I was hoping for some magic JVM property defining the java.util.Random class revision version.
First option is to check the java version and compare it against the other device's version. If they are the same it is safe (as far as I know) to assume that the Random class is the same and thus the seed and difficulty can be sent. If, however, they are different you either send all the data or check the documentation/version release notes yourself to see when the Random class was changed and then determine if all the data should be sent based on previously acquired java version identifier.
The second option is to simply always send all the data. Which is what I will personally be doing.
If you're not as lucky as I and your data exceeds the value of Multiplayer.MAX_RELIABLE_MESSAGE_LEN (in bytes) you may have to break the data into multiple messages which could get ugly but is entirely doable.
I'm using the below function to generate UUID
UUID.randomUUID().toString()
In production we have 50+ servers (application server - each is a JVM on its own) and for requests that land in these servers, as a first step we generate a UUID which essentially uniquely identifies a transaction.
What we are observing is that in Server 6 and Server 11, the UUIDs generated are matching at least for 10 to 15 messages per day which is strange because given the load i.e. about 1 million transactions a day, these UUIDs being duplicate within the same day is very odd.
This is what we have done so far
Verified the application logs - we didn't find anything fishy in there, all logs are as normal
Tried replicating this issue in the test environment with similar load in production and with 50+ servers - but this didn't happen in the test environment
Checked the application logic - this doesn't seem to be an issue because all other 48 servers except 6 and 11 which have a copy of the same code base is working perfectly fine and they are generating unique UUIDs per transaction.
So far we haven't been able to trace the issue, my question is basically if there is something at JVM level we are missing or UUID parameter that we need to set for this one off kind of an issue?
Given time, I'm sure you'll find the culprit. In the meantime, there was a comment that I think deserves to be promoted to answer:
You are generating pseudo random UUIDs at multiple locations. If you don't find other bugs, consider either generating all the pseudo random UUIDs at one location, or generate real random UUIDs
So create a UUID server. It is just a process that churns out blocks of UUIDs. Each block consists maybe 10,000 (or whatever is appropriate) UUIDs. The process writes each block to disk after the process verifies the block contains no duplicates.
Create another process to distribute the blocks of UUIDs. Maybe it is just an a web service that returns an unused block when it gets a request. The transaction server makes a request for a block and then consumes those UUIDs as it creates transactions. When the server has used most of its assigned UUIDs, it requests another block.
I wouldn't waste time wondering how UUID.randomUUID() is generating a few duplicate UUIDs per day. The odds of that happening by chance are infinitesimal. (Generating a whole series of duplicates is possible—if the underlying RNG state is duplicated, but that doesn't seem to be the case.)
Instead, look for places where a UUID stored by one server could be clobbering one stored by another. Why does this only happen between 2 servers out of 50? That has something to do with the details of your environment and system that haven't been shared.
As stated above, the chances of a legit collision are impossibly small. A more likely possibly is if the values are ever transferred between objects in an improper way.
For languages like Java that behave as pass by reference, consider the following scenario
saveObject1.setUUID(initObj.getUUID())
initObj.setUUID(UUID.randomUUID());
saveObject2.setUUID(initObj.getUUID())
In this case saveObject1 & saveObject2 will have the same value, because they are both pointed to the same object reference (initObj's UUID reference).
An issue like this seems more likely than the actual UUIDs being a collision, esp if you can reproduce it. Naturally if it doesn't happen all the time it's probably something more complex, like a rare race condition where initObj doesn't get reinitialized in time, causing saveObject1 & 2 to share the same object reference.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Youtube seems to have a unique 11 digit code for each video. the code includes 1-9,A-Z,a-z, and some symbols like +_* etc.
How would they calculate this unique code for each video? I am working on something where I'd like to assign a unique code to each record so hence the question.
My questions/concerns are:
If they make it on-the-fly (when videos are submitted) then they'd have to check whether the code prepared for the video already exists or not? That would be an expensive operation across huge dataset like theirs.
Would they run a batch job sort of thing every night or every month that creates unique codes and stash them in the DB. Then as the video is submitted it just takes a code and marks it off as "used"
Would it make sense to take the auto-generated and auto-incremented ID column for each record in the DB and then somehow convert that unique ID column to an 11 digit code?
My goal is to:
create a unique code for a record in the table.
The user can share the url with that unique code with anyone.
When someone comes in via the unique code. Then their "coming in" gets tied to the original user who shared the url with unique code.
Read up on GUID and UID in general.
Most times if you are using a database that will generate a unique id for you and then that unique id can be encoded to numbers and letters to shorten the resulting string.
http://en.wikipedia.org/wiki/Globally_unique_identifier
Shortening the string is about the way you encode the value, it doesn't actually change it.
For example the number 15 in base 10 uses two digits, in hex it uses one digit (f) in binary it uses 4 (1111).
In the same way you can use a-z, A-Z, 0-9 and get base 62 to encode numbers into strings using far fewer digits than using base 10.
It's not the only approach but (especially if you already have database rows for it) it's the simplest. You don't even need to pad to 11 unless you really want to - but adding any number of 0's at the start of the encoded string does not alter its value.
Java even provides functions to do this for you although the max radix on these ones is 36:
http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#toString%28int,%20int%29
The issue with a hashing function over the full set of possible URLs, and then check it against an indexed database, is that it removes synchronization possibilities. Consider the amount of time it takes to upload a video, checking it against their database requires just about no time, that's not the issue. The same issue happens when you think about pre-calculating: that requires synchronization over a single point of access if you want to use distributed computers, which I'm sure they do. I think your third point is probably closest to correct, and then that ID is somehow encoded into a longer number for some reason (I'm actually not sure what the advantage of it is vs. an int value; anyone got a good reason?)
Here is way to do it efficiently and also make it seem random:-
Make a hash table of M size as large as affordable.
generate first M numbers at random using lookup in hash table.
when exhausted do what algorithm suggest in the link below (sorry reusing solution to similar problem).
Generate unique phone numbers
Edit:- I know the given solution is for number but you can always translate numbers to symbols using simple mapping for each digit.
All this back and forth has caused me to do some more research regarding youtube's backend. Here's what I've come up with.
This leads me to believe that they're using MySQL to store video metadata. Some of the following will be dependent on the assumption that they are using a relational datastore.
I think that the base64 id with 11 characters is actually a base64-encoded 64 bit value. 64^11 = (2^6)^11 = 2^66, that's too close to 2^64 to be a coincidence.
I strongly suspect that a portion of this id comes from the id of the shard that the video's metadata is stored in. Let's say they devote 24 bits (16,777,216) to the shard id. They probably use this entire range, but they don't have 16 million shards. Instead, they probably assign each shard a range of these shard ids to simplify resharding. The shard id that a given video is assigned is probably pseudo-random. When a shard starts to fill up, they split it and update the ranges. Simple.
At least a portion of the remaining bits are probably an auto-incremented value local to the shard.
If there are any bits left after this, they are probably occupied by a pseudorandom number, a timestamp, or something similar. There is also the possibility that they include other implementation-specific data, but that would potentially cause big problems if they ever had to migrate so I suspect that they would shy away from this.
This question already has answers here:
How to get a unique computer identifier in Java (like disk ID or motherboard ID)?
(11 answers)
Closed 8 years ago.
I have a PC with dual cores, it has two MAC addresses : 00-1D.... & 00-21.....
Are these IDs for the two cores ?
If I want to get hold of a unique ID for this PC, how to get it with a Java call ? Maybe there is something in Java like "System.getId()" ?
Frank
MAC stands for Media Access Control. The MAC address usually represents a unique id for your network adapter(s). You must have two network adapters in your pc (LAN, WLAN?).
Have a look here this describes how to get a unique system identifier in JAVA:
How to get a unique computer identifier in Java (like disk id or motherboard id)
And .NET:
http://sowkot.blogspot.com/2008/08/generating-unique-keyfinger-print-for.html
Michael
(at the time I answered this, it was already answered what exactly a MAC address is, so I am not going to repeat it, so I just answered an unanswered question, the downvote makes no sense)
If I want to get hold of a unique ID for this PC, how to get it with a Java call
You should not bind unique identifiers to hardware, but to enduser. Hardware can be changed, the enduser not. So, ask enduser to fill some registration form (or provide a dongle, as answered by Pascal).
A MAC address is a number that identifies a Network Card Interface. You can't use that to identify a particular machine in a reliable way (a user can change his NIC, a power user can even change the MAC address dynamically).
Maybe you could use a software-protection dongle (looks like there are Java solutions). But note that even this solution doesn't solve the whole trusted client problem.
From Google :: Media Access Control address (MAC address) is a unique identifier assigned to most network adapters or network interface.
The ID's are for network interfaces. They are also not immutable, and not always unique because of this.
Look into java.net.NetworkInterface and java.net.InetAddress for methods of fetching MAC information.
The MAC is a media access control identification, the first two bytes represent the country and the 4 bytes represent the Manufacturer. No two adapters are the same, unfortunately, due to the advent of modern mass-production of NIC's, the MAC can be easily changed dynamically. Back in the old days, the NIC's consisted of DIP Switches (Dual Inline Pins) which allowed you to change the setting of the NIC such as IRQ, jumper address and so on...
They have nothing to do with processor cores, that's a separate hardware thing.
There is no portable way of getting the MAC address, theoretically you could use the ifconfig command for *nix/Linux variants. For the Windows environment you could use the ipconfig command, using either, you could search for the relevant adapter in question... as this example under Linux would show...my network adapter is called 'eth0'...
ifconfig eth0 | grep HWaddr | cut -d\t -f4
would return:
HWaddr 00:02:03:04:05:06