Tävlingsprogrammering/Uppgifter/IPv6

Från Wikibooks


IPv6

Idag identifieras datorer på internet med en 32-bitars IP-adress (t ex 83.233.162.29). Antalet tillgängliga adresser håller dock på ta slut. För att råda bot på det så har IPv6 introducerats. IP-adresserna är där 128 bitar lång och kan se ut så här (med hexadecimala siffror):

2001:0db8:85a3:0000:0000:8a2e:0370:7334

Denna representation kan komprimeras genom att ta bort några eller samtliga inledande nollor i en grupp (men minst en siffra ska vara kvar). Adressen ovan kan t ex förenklas till följande:

2001:db8:85a3:0:00:8a2e:370:7334

Dessutom får en eller flera sammanhängande grupper av nollor ersättas med dubbla kolon, ’::’. Då blir adressen ovan:

2001:db8:85a3::8a2e:370:7334

Dubbla kolon får endast användas på ett ställe i adressen.

Skriv ett program som läser in en giltig IPv6 adress från filen ip.dat (som består av en enda rad) och skriver ut en rad innehållande motsvarande adress okomprimerad.

Exempel 1

25:09:1985:aa:091:4846:374:bb

Svar

0025:0009:1985:00aa:0091:4846:0374:00bb

Exempel 2

::1

Svar

0000:0000:0000:0000:0000:0000:0000:0001

Lösning[redigera]

Det finns egentligen inga klurigheter i uppgiften, det gäller bara att implementera det hela. Varje grupp ska innehålla fyra siffror, så för varje identifierad grupp fyller man ut med nollor tills man får fyra siffror. Det ska totalt finnas åtta grupper så när man identifierar "::" fyller man ut med grupper med nollor om fyra tills man får åtta grupper. Beroende på implementation kan man behöva se upp för när "::" kommer först eller sist.

I lösningen nedan har vi också spexat till det lite genom att ta bort ett överflödigt ":" i svaret genom att skriva ut backspace (ascii-kod 8) och mellanslag, men observera att det bara är lämpligt att göra så om det är en människa som rättar uppgiften.

import java.util.*;
import java.io.*;

public class IPv6
{
	//Orka fånga exceptions. Vi är lata och säkra på vår sak.
	public static void main(String [] klein) throws FileNotFoundException
	{
		//Vi ska läsa av filen ip.dat.
		Scanner scan = new Scanner(new File("ip.dat"));

		//Komprimerad ipv6.
		String ip = scan.next();

		//10 = tal > 8. Används bara split(":") så tas "trailing" tomma grupper bort,
		// vilket vi inte vill (i synnerhet inte om IPn slutar med ::).
		String [] s = ip.split(":", 10);

		//Specialfall, ifall :: kommer först eller sist.
		if(s[0].equals(s[1]) && s[0].equals("")) s = Arrays.copyOfRange(s, 1, s.length);
		if(s[s.length-1].equals(s[s.length-2]) && s[s.length-1].equals("")) s = Arrays.copyOfRange(s, 0, s.length-1);

		//Går igenom alla grupper.
		for(int i = 0; i<s.length; i++)
		{
			//Vi har hittat den tomma gruppen orsakad av ::. Då fyller vi ut med så många
			// nollgrupper om fyra som krävs för att få totalt 8 grupper.
			if(s[i].equals("")) for(int j = 0; j<=8-s.length; j++) System.out.print("0000:");
			else
			{
				//Vi har hittat en vanlig grupp. Fyller ut med inledande nollor,
				//så att det blir fyra siffror i gruppen. (Och skriver sedan ut.)
				for(int j = s[i].length(); j<4; j++) System.out.print("0");
				System.out.print(s[i] + ":");
			}
		}

		//Skriver ut backspace (tar bort det sista ':').
		System.out.println((char)8 + " ");
	}
}