I'm writing a peer to peer application and I need a hash function for storing IP/port pairs in a java hashset. Rather than re-invent the wheel I wondered if there are already solutions out there but google has not yielded much.
Can anyone recommend a hash function for IPv4 (bonus if it works for IPv6 as well!) and a remote port number?
The port number is likely to be the same unless the client is on the same host in which case it will be sequential.
The String.hashCode() is pretty reasonable. I would simply do this:
int hash = (ip + "/" + port).hashCode();
It is "random" enough for coding purposes, so much so that it is relied upon by much of the JDK API.
Remember this mantra... "less code is good"
ip^port is about as simple as you can get
this is pretty decent as the last few bits in the IP number are essentially random (assignment of ip from the ISP)
you can expand that with ip^port|port>>>16 to avoid the issue with ending on all 0 or 1 being avoided
for IPv6 you'll need to ipv6_1^ipv6_2^ipv6_3^ipv6_4^port (with ipv6_i being the ith 32bit part)
you can also do
int hash=17;
hash=hash*5+ip;
hash=hash*5+port;
return hash
or
int hash=17;
hash=hash*5+ipv6_1;
hash=hash*5+ipv6_2;
hash=hash*5+ipv6_3;
hash=hash*5+ipv6_4;
hash=hash*5+port;
return hash
as your standard hash function which is a bit better than the standard xor because it is not commutative and you can change the order around if you feel better about it
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I want to make a simple public-key(asymmetric) encryption. It doesn't have the be secure, I just want to understand the concepts behind them. For instance, I know simple symmetric ciphers can be made with an XOR. I saw in a thread on stackexchange that you need to use trapdoor functions, but I can't find much about them. I want to say, take a group of bytes, and be able to split them someway to get a public/private key. I get the ideas of a shared secret. Say, I generate the random number of 256(not random at all :P), and I split it into 200 and 56. If I do an XOR with 200, I can only decrypt with 200. I want to be able to split numbers random and such to be able to do it asymmetrically.
OK, just a simple demo-idea, based on adding/modulo operation.
Lets say we have a modulo value, for our example 256. This is a public-known, common value.
Let's say you generate a random secret private key in the interval [1-255], for example, pri=133.
Keep secret key in the pocket.
Generate a public key, pub = 256 - pri = 123. This public key (123)
you can share to the world.
Imagine, 3rd party does not know, how to compute the private key from a public. So, they know only public key (123).
Someone from the public wants to send you an encrypted ASCII-byte. He gets his byte, and adds to it the public key by modulo 256 operation:
encrypted = (input_value + pub) % modulto;
For example, I want to send you the letter "X", ASCII code = 88 in encrypted form.
So, I compute:
(88 + 123) % 256 = 211;
I am sending you the value 211 - encrypted byte.
You decrypt it by the same scheme with your private key:
decrypted = (input_value + pri) % 256 = (211 + 133) % 256 = 88;
Of course, using the simple generation pair in this example is weak, because of
the well-known algorithm for generating the private key from the public, and anybody can easily recover the private using the modulo and public.
But, in real cryptography, this algorithm is not known. But, theoretically,
it can be discovered in future.
This is an area of pure mathematics, there's a book called "the mathematics of cyphers" it's quite short but a good introduction. I do suggest you stay away from implementing your own though, especially in Java (you want a compiler that targets a real machine for the kind of maths involved, and optimises accordingly). You should ask about this on the math or computer-science stack-exchanges.
I did get a downvote, so I want to clarify. I'm not being heartless but cyphers are firmly in the domain of mathematics, not programming (even if it is discreet maths, or the mathsy side of comp-sci) it requires a good understanding of algebraic structures, some statistics, it's certainly a fascinating area and I encourage you to read. I do mean the above though, don't use anything you make, the people who "invent" these cyphers have forgotten more than you or I know, implement exactly what they say at most. In Java you ought to expect a really poor throughput btw. Optimisations involving register pressure and allocation pay huge dividends in cypher throughput. Java is stack-based for starters.
Addendum (circa 6 years on)
Java has improved in some areas now (I have a compiler fetish, it's proper weird) however looking back I was right but for the sort-of wrong reasons, Java is much easier to attack through timing, I've seen some great use of relying on tracing compiling techniques to work out what version of software is being used for example. It's also really hard to deal with Spectre which isn't going away any time soon (I like caches.... I feel dirty saying that now)
HOWEVER: above all, don't do this yourself! Toy with it AT MOST - it's very much in the domain of mathematics, and I must say it's probably better done on paper, unless you like admiring a terminal with digits spewn all over it.
http://en.wikipedia.org/wiki/RSA_(algorithm)
Is the standard one on which the (whole) internet is based
Recently I was given a task at my company where I have to create a function like this:
boolean addrMatch(String IP, String netMask);
This has nothing to do with routing. We have a network service that will use this function. The IP parameter varies upon all requests, the netMask parameter is user-supplied. The function must tell that an actual IP address matches with the supplied netmask or not. This is something like the user tells our system to only serve requests on the public internet to a specific subset of IP addresses, not all of them.
My networking related knowledge is far from complete, so I did a deep search on the topic, but I didn't get very far.
What I know (or been told): all the two parameteres are valid IP addresses or netmasks in xxx.xxx.xxx.xxx notation. I have to do a bitwise AND on them (obviously after converting them into BitSet or at least byte[] array). But I guess this is not the complete algorithm.
So my question: what is the correct algorithm for matching an IP address with a netmask?
ps.: I'm working in Java, but I need the generic method.
A netmask is just a bitmask. Basically if address & netmask != 0 the address is in the subnet represented by the netmask. The implementation details you have to cope with are bytes instead of bits, and varying numbers of bytes depending on whether you have IPv4 or IPv6. But it's basically trivial.
I'm using the adler32 checksum algorithm to generate a number from a database id. So, when I insert a row into the database, I take the identity of that row and use it to create the checksum. The problem that I'm running into is that I just generated a repeat checksum after only 207 inserts into the database. This is much much faster than I expected. Here is my code:
String dbIdStr = Long.toString(dbId);
byte[] bytes = dbIdStr.getBytes();
Checksum checksum = new Adler32();
checksum.update(bytes, 0, bytes.length);
result = checksum.getValue();
Is there something wrong with what/how I'm doing? Should I be using a different method to create unique strings? I'm doing this because I don't want to use the db id in a url... a change to the structure of the db will break all the links out there in the world.
Thanks!
You should not be using Adler-32 as a hash code generator. That's not what it's for. You should use an algorithm that has good hash properties, which, among other things minimizes the probability of collisions.
You can simply use Java's hashCode method (on any object). For the String object, the hash code is the sum of the byte values of string times successive powers of 31. There can be collisions with very short strings, but it's not a horrible algorithm. It's definitely a lot better than Adler-32 as a hash algorithm.
The suggestions to use a cryptographically secure hash function (like SHA-256) are certainly overkill for your application, both in terms of execution time and hash code size. You should try Java's hashCode and see how many collisions you get. If it seems much more frequent than you'd expect for a 2-n probability (where n is the number of bits in the hash code), then you can override it with a better one. You can find a link here for decent Java hash functions.
Try and use a secure hash function like SHA-256. If you ever find a collision for any data that is not binary equal, you'll get $1000 on your bank account, with compliments. Offer ends if/when SHA-2 is cracked and you enter a collision deliberately. That said, the output is 32 bytes instead of 32 bits.
I have to send a short string from ANSI C application to Java application through a socket - already done. Because its important data I have to encrypt it using password like "abc123". How should I do it in the simpliest way?
By "socket" I assume you mean a TCP/IP connection. In that case you should consider using Secure Sockets Layer (SSL). SSL pretty much solves most of the security problems associated with sending data across the wire. The only thing you need to work out is how to distribute keys to each end of the pipe.
I strongly recommend that you don't roll your own system. Crypto is hard to get right so use an existing, well tested implementation.
If you're talking about a Unix domain socket then you probably don't need to bother with encryption since domain sockets are just inter-process pipes.
As mentioned it depends very much on how secure you want this to be, the sensible answer is to find a Java and C implementation of the same cryptosystem and use those.
If you are willing to accept the lower security that usually comes with home brewing these things which I assume you are by the "simplest way" in your question and assuming both the source and runtime for both ends are secure. I.E. you only need to worry about the data in transit being intercepted. You could just use whatever password you desire as a seed for a pseudo random number generator (remainder of dividing a large prime by the byte index or similar) and XOR the bytes of data with the random numbers generated. Not the most secure but would be very quick to implement.
uint8_t encrypt(uint8_t iData, size_t iPos) {
// Super large prime, our 'password', best kept super secret
const uint64_t iSeed = 32416190071;
// Mostly to stop divide by zero
// Also starting in the obvious place gives more info on the prime
const size_t iOffset = 10;
uint8_t iPad = iSeed % (iPos + iOffset);
return iPad^iData;
}
Char encrypt(char ch) {
Return (ch ^0x55);
}
Im writing a way of checking if a customers serial number matches my hard coded number. Is there a way of making this as hard to read as possible in case an undesirable gets their hands on the code?
I am working in java.
For instance (pseudo code)
if (x != y) jump out of code and return error
Cheers , apologies if this is a bit of an odd one
Security through obscurity is always a bad idea. You don't need to avoid it, but you should not trust solely on it.
Either encrypt your serials with a key you type in at startup of the service, or just specify the serials as hex or base64, not ASCII.
The normal way to do this would be to use a hash.
Create a hash of your serial code.
To validate the client serial, hash that using the same function.
If the hashes match, the serial was correct, even though the serial itself was not in the code.
By definition, a from the hash it's almost impossible to deduce the original code.
Making the code look complex to avoid being hacked never helps!
You can try SHA1 or some other one-way encrypting (MD5 not so secure but it's pretty good). Don't do this:
if (userPassword equals myHardCodedpassword)
Do this:
if (ENCRYPTED(userPassword) equals myhardcodedEncryptedpassword)
So the code-reader only can see an encrypted (and very very very difficult to decrypt) value.
Tangle the control structure of the released code?
e.g feed the numbers in at a random point in the code under a different variable and at some random point make them equal x and y?
http://en.wikipedia.org/wiki/Spaghetti_code
There is a wikipedia article on code obfuscation. Maybe the tricks there can help you =)
Instead of trying to make the code complex, you can implement other methods which will not expose your hard-coded serial number.
Try storing the hard coded number at some permanent location as encrypted byte array. That way its not readable. For comparison encrypt the client serial code with same algorithm and compare.