summaryrefslogtreecommitdiffstats
path: root/source/util/Hasher.java
blob: 0458e94ddee8a130b1a67aa029d6d0c444d41759 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
 * Created on Mar 1, 2004
 * Algorithm:
 * Copyright (c) 2004 David Hammerton
 *
 * port to java:
 * Copyright (c) 2004 Joseph Barnett
 */
package itunes.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @author jbarnett
 */
public class Hasher {	
		//taken from calculations in libopendaap
	//private static String staticHash = "98814088228B81E0AB021433618EC27B";
	private static String calcHash = "";
	private static boolean staticCalculated = false;
	
	private static final String hexchars = "0123456789ABCDEF";
	private static final String appleCopyright = "Copyright 2003 Apple Computer, Inc.";
	private static MessageDigest md;
	
	private static final int HASH_SIZE = 32;
	
	static {
		try {
			md = MessageDigest.getInstance("md5");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
	
	private static String DigestToString(byte[] digest)
	{
		String string="";
		int i;
		for (i = 0; i < digest.length; i++)
		{
			byte tmp = digest[i];
			string += hexchars.charAt((tmp >> 4) & 0x0f);
			string += hexchars.charAt(tmp & 0x0f);
		}
		return string;
	}	
	
	private static synchronized void calculateStaticHash() {
		if (staticCalculated)
			return;
		for (int i = 0; i < 256; i++) {
			if ((i & 0x80) != 0)
				md.update("Accept-Language".getBytes());
			else
				md.update("user-agent".getBytes());

			if ((i & 0x40) != 0)
				md.update("max-age".getBytes());
			else
				md.update("Authorization".getBytes());

			if ((i & 0x20) != 0)
				md.update("Client-DAAP-Version".getBytes());
			else
				md.update("Accept-Encoding".getBytes());

			if ((i & 0x10) != 0)
				md.update("daap.protocolversion".getBytes());
			else
				md.update("daap.songartist".getBytes());

			if ((i & 0x08) != 0)
				md.update("daap.songcomposer".getBytes());
			else
				md.update("daap.songdatemodified".getBytes());

			if ((i & 0x04) != 0)
				md.update("daap.songdiscnumber".getBytes());
			else
				md.update("daap.songdisabled".getBytes());

			if ((i & 0x02) != 0)
				md.update("playlist-item-spec".getBytes());
			else
				md.update("revision-number".getBytes());

			if ((i & 0x01) != 0)
				md.update("session-id".getBytes());
			else
				md.update("content-codes".getBytes());	
			
			String newHash =DigestToString(md.digest()); 
			calcHash += newHash;
		}
		staticCalculated = true;
	}
	
	public static String GenerateHash(String url, int accessIndex) {
		int start = HASH_SIZE * accessIndex;
		int end = start + HASH_SIZE;
		calculateStaticHash();	
		md.update(url.getBytes());
		md.update(appleCopyright.getBytes());
		md.update(calcHash.substring(start, end).getBytes());
		return DigestToString(md.digest());
	}
}