How to compare two CSV file? - java

I have two CSV file 1st one IP Geo-location CSV file and second one have date time and IP address how to compare both file and make new CSV file have date time IP address and IP location(country name).How to make it in java?
1st File
18102015 11:35:59 93.178.13.37:2065
18102015 11:36:00 93.178.13.37:2078
18102015 11:36:21 93.178.13.37:7251
18102015 11:37:05 222.35.153.160:502
18102015 11:37:05 222.35.153.160:5050
2nd File
93.178.0.0 93.178.63.255 1571946496 1571962879 SA Saudi Arabia
93.178.64.0 93.178.127.255 1571962880 1571979263 RU Russian Federation
222.16.0.0 222.95.255.255 3725590528 3730833407 CN China
I want Result:
18102015 11:35:59 93.178.13.37 2065 SA Saudi Arabia
18102015 11:36:00 93.178.13.37 2078 SA Saudi Arabia
18102015 11:36:21 93.178.13.37 7251 SA Saudi Arabia
18102015 11:37:05 222.35.153.160 5029 CN China
18102015 11:37:05 222.35.153.160 5050 CN China

Hints:
Think of a dotted IP address as 4 octets of a 32 bit number. For example, the IP address 93.178.63.255 is really (93*(2^24)) + (178*(2^16)) + (63*(2^8)) + 255. Do the math, and you come up with a number that represents the IP address.
The second file has IP ranges (low to high). If you convert the low and high IP addresses of the range, you'll come up with two numbers. Therefore, if you're trying to detect if a certain IP address (from file #1) is within a range (in file #2), it's simple. if IP >= lowIP && IP <= highIP it's in the range.
Further advice: parse file #2 and create objects for each of them. The object will have most notably the starting IP address, the ending IP address, and the country. Then you can parse file #1, search within your collection of objects for a match, and then output what you need to.

Related

Java string indexing make me confused

So i need to gather data from my db, it's holiday date in my country, the data comes like this
Example 1 : THU 21 May Ascension Day of Jesus Christ *ICDX GOLD open for
Example 2 : MON-THU 28-31 Dec Substitute for Commemoration of Idul Fitri Festival
So i need to get data from days, dates, and the holiday name, for get data from example 1 i'm using code like this
public static void main(String[] args) {
String ex1 = "THU 21 May Ascension Day of Jesus Christ *ICDX GOLD open for";
String ex2 = "MON-THU 28-31 Dec Substitute for Commemoration of Idul Fitri Festival ";
String[] trim1 = ex1.trim().split("\\s+"); //to split by space
String[] trim2 = ex1.trim().split(" "); //to split by 3 space so i got the data from multiple space as delimiter
System.out.println("DAY " +trim1[0]);//display day
System.out.println("DATE " +trim1[1] +trim1[2]+"2020");//display date
System.out.println("HOLIDAY NAME " +trim2[3]);//dispay holiday name
}
The Output come like this
DAY MON
DATE 21May2020
HOLIDAY NAME Ascension Day of Jesus Christ
and just like what i need, but when come to example 2, i can't use same code because the space is different, how to get the data i need with example 1 and 2 with same code.
i am new in java so i'm sorry if my question looking dumb, i hope you can help me.Thanks
.split("\\s+") will split at any space, including multiple spaces. Eg. it will split at 1 space or more.
This means that you are able to split at any amount of spaces (what you want). However, this will also split your text comments. You are able to limit the length of the array produced (the amount of times it is split) using .split(regex, n), which will result in an array of n-1 size at most. See this for more details
As for splitting out your two textual comments, I cannot see a way to do this.
Substitute for Commemoration of Idul Fitri Festival "; contains no way of telling what is the first text comment and the second.
It seems quite strange to me that you receive information from your database like this, I would recommend seeing if there are other options for doing this. There is almost certainly a way to get seperate fields.
If have the ability to change all the information in the database, you could put single quotes (') or some other seperator, which you would then be able to split out the two pieces of text.
This is basically what #DanielBarbarian suggested: Since the information seems to always start at the same indexes, you can just use those to get what you need.
String ex1 = "THU 21 May Ascension Day of Jesus Christ *ICDX GOLD open for";
String ex2 = "MON-THU 28-31 Dec Substitute for Commemoration of Idul Fitri Festival ";
String day = ex2.substring(0, 8).trim();
String date = ex2.substring(8, 14).trim() + ex2.substring(14, 22).trim() + "2020";
String name = ex2.substring(22);
System.out.println("DAY " + day);// display day
System.out.println("DATE " + date);// display date
System.out.println("HOLIDAY NAME " + name);// dispay holiday name

how to search for the ip addresses in cidr notation

I need to search for the entries in the mysql database with following ipaddress “192.168.0.1/20 ”
Note: ip addresses stored are varchars (ex. 192.168.0.3,192.168.0.4)
Address: 192.168.0.1 11000000.10101000.0000 0000.00000001
Netmask: 255.255.240.0 = 20 11111111.11111111.1111 0000.00000000
Wildcard: 0.0.15.255 00000000.00000000.0000 1111.11111111
=>
Network: 192.168.0.0/20 11000000.10101000.0000 0000.00000000
HostMin: 192.168.0.1 11000000.10101000.0000 0000.00000001
HostMax: 192.168.15.254 11000000.10101000.0000 1111.11111110
Broadcast: 192.168.15.255 11000000.10101000.0000 1111.11111111
Hosts/Net: 4094 Class C, Private Internet
my solution is to find to the network address from given cidr notation (replace 0 with "*") and search for 192.168.*.* entries in database as they are stored in strings. It works but I am not sure whether this is correct
can any point out the problem or more optimal solution than this?
The following works if you have single IP address per VARCHAR field.
Correct way to match IP addresses against their network using netmask is through INET_ATON()/INET_NTOA().
There are several steps, though. First use the following to convert your length to subnetmask:
SET #l=20;
SELECT INET_NTOA(0xffffffff >> (32-#l) << (32-#l));
That's just to convey the idea, to make this useful you could do the following:
SELECT 0xffffffff >> (32-#l) << (32-#l) INTO #mask;
For the actual matching of the address against your network address you can use INET_ functions with bitwise operators, for example:
SET #l=20;
SET #nw='192.168.0.0';
SELECT 0xffffffff >> (32-#l) << (32-#l) INTO #mask;
SELECT * FROM yourtable
WHERE (INET_ATON(addrfield) & #mask) = INET_ATON(#nw);
Of course you may roll this into a single statement like:
SELECT * FROM yourtable
WHERE (INET_ATON(addrfield) & (0xffffffff >> (32-#l) << (32-#l))) = INET_ATON('192.168.0.0');

Getting IP address list between two IP addresses

I am writing a program that gets From IP address and To IP address from the user and displays the list of IP addresses between them. For example, if the user gives 10.0.0.1 and 10.0.0.5 then I will display the five IP addresses between these two. The current solution that is coming in my mind are:
To have a list of all IP addresses and then look for the resultant IP address list
Use a nested loop
What solution should I adopt between these (or suggest a better solution)? For the first solution, what is the link for IP address table/list?
What is the solution in terms of JavaScript or Java?
First split the IP addresses with .. From the first IP address, start increasing the fourth part up to 255 and then add 1 to the third part and set the fourth one to 1. Until you reach the to IP address.
IP address bytes -> bits -> Int32
From: 10.0.10.10 -> 00001010 00000000 00001010 00001010 -> 167774730
To: 10.1.45.1 -> 00001010 00000001 00101101 00000001 -> 167849217
Start count from From to To and just check the unwanted bytes which is 11111111 and 00000000.
That's all.
The "dot"-writing is for humans. For computers, it is one 4-byte-number. So parse it to a number. Then you will get all addresses in the range by simply increasing a number until the bound is reached and format them back for output.
I was experimenting in an updated jsFiddle, and finally I came to the solution below. The following code should work for all IP addresses. You have to provide a start and end IP address in hex (since it is easy, I did not write code for it).
var startIp = 0x0A000001,
endIp = 0x0A000F05;
var temp, list = [],str;
for(var i=startIp ; i <= endIp ; i++){
temp = (i).toString(16);
str ='';
if(temp.length == 7){
temp = "0"+temp;
}
for(var k=temp.length-1; k >= 0 ; k-=2){
str = parseInt(temp[k-1] + "" + temp[k], 16) +"." + str ;
}
document.write(temp + " " + str+ "<br>");
list.push(str.substring(0, str.length-1));
}
?
If you know enough to get the addresses (from the network or from the file system or user input), you can test the address itself with subtraction and get the number of IP addresses right there.
This is simplified, but you will get it if you know about addresses: 000044-000002 = 000042.

Would regex be a good choice to parse SMTP received lines

I want to parse elements of RFC822 (SMTP) "Received" lines, which are defined formally in the spec, e.g.:
atom = 1*
[...]
received = "Received" ":" ; one per relay
["from" domain] ; sending host
["by" domain] ; receiving host
["via" atom] ; physical path
*("with" atom) ; link/mail protocol
["id" msg-id] ; receiver msg id
["for" addr-spec] ; initial form
";" date-time ; time received
[...]
msg-id = "" ; Unique message id
[...]
addr-spec = local-part "#" domain ; global address
etc. for domain, date-time, etc.
Here's a real example:
Received: from ll-194.132.162.89.kv.sovam.net.ua (ll-194.132.162.89.kv.sovam.net.ua [83.170.243.194] (may be forged)) by raq2073.uk2.net (8.10.2/8.10.2) with ESMTP id lASHDDE10765 for <johnsmithsvt#matts.co.uk>; Wed, 28 Nov 2007 17:13:13 GMT
Would regex be a good strategy to capture the parts of a received line?
I realize that many SMTP servers don't format received lines properly (in real life).
Otherwise, does anyone know of a library in Java that does this well?
Edit Here's a fiddle showing a regex and tests that I've banged on for a while, which seems to work.
Received:\s+(?:from\s+(.+?))?(?:\(qmail (.+?)\))?(?:\s+by\s+(.+?))?(?:\\s+via\s+(.+?))?(?:\s+with\s+(.+?))?(?:\;?\s+id\s+(.+?))?(?:\s+for\s+(.+?))?(?:;\s*(?!.*\;.*)(.+))?$
The choice really depends on exactly what you want to achieve.
For capturing specific parts of a Receiver-line (e.g. 'give me the From-part'), regexes are awesome.
If you need a full-fledged parser for this grammar, then regexes alone will not suffice. Especially the addr-spec has so many special cases that a regex cannot hope to handle each one correctly (explanation). Regexes are not parsers.
Last time I needed an actual parser, I wrote my own using JavaCC. I would only recommend going down that road if you know a thing or two about grammars and parsing.

Search hierarchical text in Oracle database

Table = BLOCK (Has composite unique index both the columns)
IP_ADDRESS CIDR_SIZE
========= ==========
10.10 16
15.0 16
67.7 16
18.0 8
Requirements:
Sub block is not allowed. For e.g. 67.7.1 and 24 is not allowed as this is child of 67.7. In other words, if there is any IP address in the database that matches beginning portion of new IP, then it should fail. Is it possible for me to do it using a Oracle SQL query?
I was thinking of doing it by...
Select all records into the memory.
Convert each IP into its binary bits
10.10 = 00001010.00001010
15.0 = 00001111.00000000
67.7 = 01000011.00000111
18.0 = 00010010.00000000
Convert new IP into binary bit. 67.7.1 = 01000011.00000111.00000001
Check to see if new IP binary bits start with existing IP binary bits.
If true, then the new record exists in the database.
For example, new binary bit 01000011.00000111.00000001 does start with existing ip (67.7) binary bits 01000011.00000111. Rest of records don't match.
I am looking to see if there a Oracle query that can do this for me, that is return the matching IP addresses from the database. I checked out Oracle's Text API, but didn't find anything just yet.
Is there a reason you can't use the INSTR function?
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions068.htm#i77598
I'd do something like a NOT EXISTS clause that checks for INSTR(b_outer.IP_ADDRESS,b_inner.IP_ADDRESS) <> 1
*edit: thinking about this you'd probably need to check to see if the result is 1 (meaning the potential IP address matches starting at the first character of an existing IP address) as opposed to a general substring search as I originally had it.
Yes you can do it in SQL by converting IP's to numbers and then ensureing this is not a record with a smaller cidr size that gives the same ipnum when using its cidr size.
WITH ipv AS
( SELECT IP.*
, NVL(REGEXP_SUBSTR( ip, '\d+', 1, 1 ),0) * 256 * 256 * 256 -- octet1
+ NVL(REGEXP_SUBSTR( ip, '\d+', 1, 2 ),0) * 256 * 256 -- octet2
+ NVL(REGEXP_SUBSTR( ip, '\d+', 1, 3 ),0) * 256 -- octet3
+ NVL(REGEXP_SUBSTR( ip, '\d+', 1, 4 ),0) AS ipnum -- octet4
, 32-bits AS ignorebits
FROM ips IP
)
SELECT IP1.ip, IP1.bits
FROM ipv IP1
WHERE NOT EXISTS
( SELECT 1
FROM ipv IP2
WHERE IP2.bits < IP1.bits
AND TRUNC( IP2.ipnum / POWER( 2, IP2.ignorebits ) )
= TRUNC( IP1.ipnum / POWER( 2, IP2.ignorebits ) )
)
Note: My example uses the table equivalent to yours:
SQL> desc ips
Name Null? Type
----------------------------------------- -------- ----------------------------
IP NOT NULL VARCHAR2(16)
BITS NOT NULL NUMBER

Categories

Resources