How to get cpu-id in java? - java

I want to create an encryption with java.Is there anyway to get CPU Id or anything that be unique in PC such as BIOS or ...
for example System.getCpuId(); it is just an example 😉
Thanks a lot ...

So you want a unique number (or string?) that identifies the user's computer? Or at least unique enough that the chance of a duplicate is very low, right?
You can get the Mac address of the network interface. This is making many assumptions, but it may be good enough for your needs:
final byte[] address = NetworkInterface.getNetworkInterfaces().nextElement().getHardwareAddress();
System.out.println("address = " + Arrays.toString(address));
This gives you an array of bytes. You can convert that to an id in several ways... like as a hex string.
Expect support though, when people replace bits of hardware in their computer.

I think such OS specific command is not available in Java.
This link shows a way to run it on windows.

You can't (reliably) get hardware information in pure Java. You would have to use JNA or JNI. Can you clarify what kind of encryption system you're building, and why you need the hardware info?
EDIT: Steve McLeod has noted that Java has a NetworkInterface.getHardwareAddress() method. However, there are serious caveats, including the fact that not all Java implementations allow access to it, and MAC addresses can be trivially forged.

You should also consider a machine can have more than one CPU/NIC/whatever and thus more than one IDs.

if you need unique id you can use UUID :
import java.util.UUID;
public class GenerateUUID {
public static final void main(String... aArgs){
//generate random UUIDs
UUID idOne = UUID.randomUUID();
UUID idTwo = UUID.randomUUID();
log("UUID One: " + idOne);
log("UUID Two: " + idTwo);
}
private static void log(Object aObject){
System.out.println( String.valueOf(aObject) );
}
}
Example run :
>java -cp . GenerateUUID
UUID One: 067e6162-3b6f-4ae2-a171-2470b63dff00
UUID Two: 54947df8-0e9e-4471-a2f9-9af509fb5889

There's no way to get hardware information directly with Java without some JNA/JNI library. That said, you can get "somewhat unique, system-specific values" with System.getEnv(). For instance,
System.getEnv("COMPUTERNAME")
should return computer's name in a Windows system. This is, of course, higly unportable. And the values can change with time in the same system. Or be the same in different systems. Oh, well...

What you are really looking for is a good entropy source, but I would actually suggest you investigate the Java Cryptography Architechture as it provides a framework for this, so you can concentrate on your actual algorithm.
http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html

Related

Java Library to validate and compare MAC address

We have a Java web service that gets a String representing a MAC address. We want to validate if the given String actually matches the required format. Further we want to create a normalized form to make them comparable.
I searched quite a while but found only some "loose regular expressions". We would really prefer to have a library that can parse different formats and return a normalized (String) representation (i.e. 01-23-45-67-89-ab and 01:23:45:67:89:ab would return the same representation and be comparable).
I expected to find some mature and well tested library, which could do that kind of task. Can anyone please point me to it? I just cannot believe that it doesn't exist yet.
I would be very thankful to not see any RegExes as possible solutions (we know how to do that if necessary).
The IPAddress Java library will do it. The javadoc is available at the link. Disclaimer: I am the project manager.
The library will read various common formats for MAC addresses, like aa:bb:cc:dd:ee:ff, aa-bb-cc-dd-ee-ff, aabb.ccdd.eeff, it supports addresses that are 48 or 64 bits, and also allows you to specify ranges of addresses like aa-ff:bb:cc:*:ee:ff
Verify if an address is valid:
String str = "aa:bb:cc:dd:ee:ff";
MACAddressString addrString = new MACAddressString(str);
try {
MACAddress addr = addrString.toAddress();
...
} catch(AddressStringException e) {
//e.getMessage provides validation issue
}
The library is well tested, it has a test suite with thousands of tests.
mature and well tested library
To verify MAC addresses? It's 6 bytes in hex optionally separated by a delimiter. It's a homework assignment or light interview question, no need to write a library. My solution is 10 lines, and it's more paranoid than necessary...

How to generate incremental identifier in java

I have requirement in which I continuously receive messages that needs to be written in a file. Every time a new message is received it needs to be written in a separate file. What I want is to generate an unique identifier to be used as a file-name. I also want to preserve the order of the messages as well. By this I mean, the identifier generated as a file-name should always be incremental.
I was using UUID.randomUUID() to generate file-names but the problem with this approach is that UUID only assures randomness of the identifier but is not incremental. As a result I am losing the ordering of the file (I want file generated first should appear first in the list).
Approaches known
Can use System.currentTimeMillis() but I can receive multiple messages at same time stamp.
2.Another approach could be to implement static long value and increment it whenever a file is to be created and use the long value as a file-name. But I am not sure about this approach. Also it doesn't seem to be a proper solution to my problem. I think there could be far better solutions than this one.
If someone could suggest me a better solution to this problem, will be highly appreciated.
If you want your id value to uniformly rise even between server restarts, then you must either base it on the system time or have some elaborately robust logic that persists the last ID used. Note that achieving robustness on its own is not hard, but achieving it in a performant and scalable way is.
If you additionally need the id to be unique across multiple nodes in a redundant server cluster, then you need even more elaborate logic, which definitely involves a persistent store to which all the boxes synchronize access. Making this performant is, of course, even harder.
The best option I can see is to have a quite long ID so there's room for these parts:
System.currentTimeMillis for long-term uniqueness (across restarts);
System.nanotime for finer granularity;
a unique id of each server node (determined in a platform-specific way).
The method will still have to remember the last value generated and retry in case of a duplicate. It won't have to retry too many times, though, just until the next nanoTime clock tick—it could even busy-wait for it.
Sketch of code without point 3 (single-node implementation):
private static long lastNanos;
public static synchronized String uniqueId() {
for (;/*ever*/;) {
final long n = System.nanoTime();
if (n == lastNanos) continue;
lastNanos = n;
return "" + System.currentTimeMillis() + n;
}
}
Ok, my hands up. My last answer was fairly flaky and I've deleted it.
Keeping with the spirit of the site, I thought I'd try a different tac.
If you say you are keeping these messages in a single file then you could try something like creating an unique Id out of the size of the file?
Before you write the message to the file it's id could be the current size of the file.
You could add the filename + size as the id if these messages need to be unique across a number of files.
I'll leave the hot potato of synchronization to another day. But you could wrap all of this up in a syncronized object that keeps track of things.
Also, I am assuming that any messages written to the file will not be removed in the future.
ADDITIONAL NOTE:
You could create an message processing object that opens the file on construction (or via a create method).
This object will get the initial size of the file and this will be used as the unique id.
As each message is added (in a synchronized manner), the id is incremented by the size of the message.
This would address the performance issues. Will not work if more than one JVM/Node accesses the same file.
Skeletal Idea:
public class MessageSink {
private long id = 0;
public MessageSink(String filename) {
id = ... get file size ..
}
public synchronized addMessage(Message msg) {
msg.setId(id);
.. write to file + flush ..
.. or add to stack of messages that need to be written to file
.. at a later stage.
id = id + msg.getSize();
}
public void flushMessages() {
.. open file
.. for each message in stack write ...
.. flush and close file
}
}
I had the same requirement and found a suitable solution. Twitter Snowflake uses a simple algorithm to generate sortable 64bit (long) ids. Snowflake is written on Scala but the approach is simple and could be easily used in a Java code.
id is composed of:
timestamp - 41 bits (millisecond precision w/ a custom epoch gives us 69 years);
machine id - 10 bits (MAC address could be used as a hardware id);
sequence number - 12 bits - rolls over every 4096 per machine (with protection to avoid rollover in the same ms)
Formula looks like: ((timestamp - customEpoch) << timestampShift) | (machineId << machineIdShift) | sequenceNumber;
Shift for each component depends on it's bits position in ID.
Detailed description and source code could be found at github:
Twitter Snowflake
Basic Java implementation of the Snowflake algorithm

A function that generates a boolean that differs between computers, but not within the same computer. Possible?

This is kind of a weird question. I'd like to write a Java function that will either return true or false. It will ALWAYS return either true or false for the same computer, even if the program has been purged from the computer and reinstalled (that is, no state is allowed.) It will return the same value no matter where in the program it is called, what time it is, if it's a Tuesday, etc.
My second requirement is that for all of the computers in the world it there should be anywhere from a 50/50 to a 30/70 split in what the function returns. That is, at least 30% of computers need to generate the less-likely result of the function.
My third requirement (the tricky one) is that what causes the true/false split won't be obvious to users. So splitting along operating system lines isn't okay, since that's obvious.
Any thoughts?
Update: True, "same computer" doesn't have much meaning since computers are made of changeable parts. It's fine for the value to change if a piece of hardware is replaced.
Well, the most simple solution would be to just use the last digit of the mac address to return
true or false based on if its even or odd.
This will ensure that on the same machine it always returns the same for a machine and it will return true on half the machines in the world.
import java.net.*;
/**
*
* #author nick
*/
public class HardwareTruthGen {
//Instance Variables
static InetAddress addr;
static NetworkInterface net;
static byte[] macAddr;
static boolean hardware;
static {
try{
addr = InetAddress.getLocalHost();
net = NetworkInterface.getByInetAddress(addr);
macAddr = net.getHardwareAddress();
//If mac address ends in an even number return true otherwise return false
if((macAddr[(macAddr.length - 1)] % 2) == 0)
hardware = true;
else
hardware = false;
}
catch (Exception ex){
}
}
public static boolean macTrue(){ return hardware;}
}
Your specification lacks specificity, particularly in the definition of ALWAYS and same computer. Everything else hinges on your assumptions of those invariants.
Lets assume ALWAYS means "now" and same computer means "current JVM process", wildly wrong but illustrates the assumptions determine the outcome of your 2nd and 3rd requirements.
Collect data on some hardware, possibly all hardware and generate a hash based on that hardware data. The hardware detected defines same computer and by implication requires ALWAYS to be "now".
8aca8asad8ae8f8fs8sv8sdfsf8sfs8a8faa
There, that's mine :)
Now you can map the minimum and maximum possible values for this hash, and distribute your boolean valueOf accordingly.
The 3rd requirement is security by obscurity and thus, by definition, "you're doing it wrong" ;)
Simple. Have a function f(a, b) where a is whether this function has been executed on this computer before, and b gives the last result on this computer (or false if a is false). Then, for correct input, you can compute f as a ? b : (boolean)random(0 or 1).
Ok, let's put on our hypothectical Computer Science hat. To really be able to reproduce the desired behavior on the machine with no state, there has to be a repeatable function inherently present. My first thought was to examine some register, and switch off of the value of the zero bit, without changing it of course. That may not be random enough because it depends on what instructions the CPU has been executing prior to your code peeking under the covers.
The second thought was to use some inheirent value of the machine, like hostname or CPU-ID, but they can either change (hostname) or may not exist on all platforms.
That's when I noticed the 'Java' tag and realized that you might have an uphill road in front of you if you don't want to write cross-platform JRI (don't blame you) or rely on an intrinsic value of the JRE which could change when the next version comes out or they switch vendors.
You may be able to use clock-speed, even if you have to do your own timing loop and and use compliation switches to prevent the JIT compiler/JRE from optimizing the routine. That could give you a range of values to switch on. No direct speeds; find the number of milliseconds a specific instruction takes, and switch on whether the value is odd/even.
There's more things to try but they just get more wild the longer I think on the problem. Please update this post with an answer of what you end up using. I'd like to know how it turns out.
You can use systems hostname or ip address and encrypt it or a seed for a randomizer.
int seed = InetAddress.getLocalHost().hashCode();
// or
int seed = InetAddress.getLocalHost().getHostName().hashCode();
boolean evenRandom = new Random(seed).nextBoolean();
boolean rand_30_70 = new Random(seed).nextInt(100) > 30;
It should be noted that the SecurityManager can change this result or prevent the hostname being obtained. It can also prevent you obtaining a MAC address and any other low-level system information you might want to get.

Why does my UUID use too much time?

String s = UUID.randomUUID().toString();
return s.substring(0,8) + s.substring(9,13) + s.substring(14,18) +
s.substring(19,23) + s.substring(24);
I use JDK1.5's UUID, but it uses too much time when I connect/disconnect from the net.
I think the UUID may want to access some net.
Can anybody help me?
UUID generation is done locally and doesn't require any alive network connection.
Quoting the API odc:
public static UUID randomUUID()
Static factory to retrieve a type 4 (pseudo randomly generated) UUID.
The UUID is generated using a
cryptographically strong pseudo random
number generator.
Your delay is probably being caused by the intialization of the cryptographically strong RNG - those take some time, and might even depend on the presence of a network connection as a source of entropy. However, this should happen only once during the runtime of the JVM. I don't see a way around this problem, though.
The javadoc for UUID http://java.sun.com/j2se/1.5.0/docs/api/java/util/UUID.html has some good information on how the UUID is generated. It uses the time and clock frequency to generate the UUID. Like sharptooth says, no network interface is required. Is there possibly some other concurrent process running that could possibly be causing this problem?
What's the purpose of those s.substring calls? It looks like you're returning the original string.
If you're appending 5 Strings together, over a large set of data, that could be the issue. Try to use StringBuffer. It's amazing the difference that can make when concatenating more than 1-2 Strings together, especially for larger datasets
For older versions of Java (6 and earlier maybe?), there's a bug in Random that causes it to iterate over the entire temp directory. We've seen seed generation take 10 minutes on some egregiously bad build machines at NVIDIA. You might want to check the size of your temp dir.
Compare: http://www.docjar.com/html/api/sun/security/provider/SeedGenerator.java.html
To: http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules/j2me/sun/security/provider/SeedGenerator.java.htm

Generating a globally unique identifier in Java

Summary: I'm developing a persistent Java web application, and I need to make sure that all resources I persist have globally unique identifiers to prevent duplicates.
The Fine Print:
I'm not using an RDBMS, so I don't have any fancy sequence generators (such as the one provided by Oracle)
I'd like it to be fast, preferably all in memory - I'd rather not have to open up a file and increment some value
It needs to be thread safe (I'm anticipating that only one JVM at a time will need to generate IDs)
There needs to be consistency across instantiations of the JVM. If the server shuts down and starts up, the ID generator shouldn't re-generate the same IDs it generated in previous instantiations (or at least the chance has to be really, really slim - I anticipate many millions of presisted resources)
I have seen the examples in the EJB unique ID pattern article. They won't work for me (I'd rather not rely solely on System.currentTimeMillis() because we'll be persisting multiple resources per millisecond).
I have looked at the answers proposed in this question. My concern about them is, what is the chance that I will get a duplicate ID over time? I'm intrigued by the suggestion to use java.util.UUID for a UUID, but again, the chances of a duplicate need to be infinitesimally small.
I'm using JDK6
Pretty sure UUIDs are "good enough". There are 340,282,366,920,938,463,463,374,607,431,770,000,000 UUIDs available.
http://www.wilybeagle.com/guid_store/guid_explain.htm
"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, 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"
http://en.wikipedia.org/wiki/Universally_Unique_Identifier
public class UniqueID {
private static long startTime = System.currentTimeMillis();
private static long id;
public static synchronized String getUniqueID() {
return "id." + startTime + "." + id++;
}
}
If it needs to be unique per PC: you could probably use (System.currentTimeMillis() << 4) | (staticCounter++ & 15) or something like that.
That would allow you to generate 16 per ms. If you need more, shift by 5 and and it with 31...
if it needs to be unique across multiple PCs, you should also combine in your primary network card's MAC address.
edit: to clarify
private static int staticCounter=0;
private final int nBits=4;
public long getUnique() {
return (currentTimeMillis() << nBits) | (staticCounter++ & 2^nBits-1);
}
and change nBits to the square root of the largest number you should need to generate per ms.
It will eventually roll over. Probably 20 years or something with nBits at 4.
From memory the RMI remote packages contain a UUID generator. I don't know whether thats worth looking into.
When I've had to generate them I typically use a MD5 hashsum of the current date time, the user name and the IP address of the computer. Basically the idea is to take everything that you can find out about the computer/person and then generate a MD5 hash of this information.
It works really well and is incredibly fast (once you've initialised the MessageDigest for the first time).
why not do like this
String id = Long.toString(System.currentTimeMillis()) +
(new Random()).nextInt(1000) +
(new Random()).nextInt(1000);
if you want to use a shorter and faster implementation that java UUID take a look at:
https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/main/java/org/spf4j/concurrent/UIDGenerator.java
see the implementation choices and limitations in the javadoc.
here is a unit test on how to use:
https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/test/java/org/spf4j/concurrent/UIDGeneratorTest.java

Categories