Codebase list pipal / 3f0456e
Imported Upstream version 2.0 Devon Kearns 11 years ago
5 changed file(s) with 1714 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 Pipal, Password Analyser
1 ========================
2
3 Copyright(c) 2012, Robin Wood <[email protected]>
4
5 On most internal pen-tests I do I generally manage to get a password dump from
6 the DC. To do some basic analysis on this I wrote Counter and since I originally
7 released it I've made quite a few mods to it to generate extra stats that are
8 useful when doing reports to management.
9
10 Recently a good friend, n00bz, asked on Twitter if anyone had a tool that he
11 could use to analyse some passwords he had. I pointed him to Counter and said if
12 he had any suggestions for additions to let me know. He did just that and over
13 the last month between us we have come up with a load of new features which we
14 both think will help anyone with a large dump of cracked passwords to analyse.
15 We also got some input from well known password analysts Matt Weir and Martin
16 Bos who I'd like to give a big thanks to.
17
18 I have to point out before going on, all this tool does is to give you the stats
19 and the information to help you analyse the passwords. The real work is done by
20 you in interpreting the results, I give you the numbers, you tell the story.
21
22 Seeing as there have been so many changes to the underlying code I also decided
23 to change the name (see below) and do a full new release.
24
25 So, what does this new version do? The best way to describe it is to see some
26 examples so go to the Pipal project page at www.digininja.org/projects/pipal.php
27 for a full walk through of a sample analysis.
28
29 Install / Usage
30 ===============
31 The app will only work with Ruby 1.9.x, if you try to run it in any previous
32 versions you will get a warning and the app will close.
33
34 Pipal is completely self contained and requires no gems installing so should
35 work on any vanilla Ruby install.
36
37 Usage is fairly simple, -? will give you full instructions:
38
39 $ ./pipal.rb -?
40 pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
41
42 Usage: pipal [OPTION] ... FILENAME
43 --help, -h: show help
44 --top, -t X: show the top X results (default 10)
45 --output, -o : output to file
46 --external, -e : external file to compare words against
47 --gkey <Google Maps API key>: to allow zip code lookups (optional)
48
49 FILENAME: The file to count
50
51 When you run the app you'll get a nice progress bar which gives you a rough idea
52 of how long the app will take to run. If you want to stop it at any point
53 hitting ctrl-c will stop the parsing and will dump out the stats generated so
54 far.
55
56 The progress bar is based on a line count from the file which it gets this using
57 the wc command. If it can't find wc it will make a guess at the number of lines
58 based on the file size and an average line length of 8 bytes so the progress bar
59 may not be fully accurate but should still give you an idea.
60
61 The Google Maps API key is supposed to be used by Google to only allow access to
62 their API to registered users. I assumed this was true and registered for a key
63 but in putting together this release I found that it will take any value and
64 still do the look up. This may be a bug at the Google end or deliberate and may
65 change any any time so I'd suggest grabbing a key just in case. To use it you
66 can either edit the script and put the key into the constant on line 35 or you
67 can pass it on the command line every time. If you are going to hope that you
68 don't need a valid key then just put X in as the value as without something
69 Pipal won't try to perform a look up.
70
71 Version History
72 ===============
73
74 Version 2 - Two big changes, the first a massive speed increase. This patch was
75 submitted by Stefan Venken who said a small mention would be good enough, I want
76 to give him a big mention. Running through the LinkedIn lists would have taken
77 many many hours on version 1, version 2 went through 3.5 million records in
78 about 15 minutes. Thank you.
79
80 Second change is the addition of US area and zip code lookups. This little
81 feature gives some interesting geographical data when ran across password lists
82 originating in the US. The best example I've seen of this is the dump from the
83 Military Singles site where some passwords could be obviously seen to be grouped
84 around US military bases. People in the UK don't have the same relationship with
85 phone numbers so I know this won't work here but if anyone can suggest any other
86 areas where this might be useful then I'll look at building in some kind of
87 location awareness feature so you can specify the source of the list and get
88 results customized to the correct area or just run every area and see if a
89 pattern emerges.
90
91 A non-code-base change is for version 2 is the move from hosting the code myself
92 to github. This is my first github hosted project so I may get things wrong, if
93 I do, sorry. A number of people asked how they could submit patches so this
94 seems like the best way to do it, lets hope it works out.
95
96 Version 1 - Was a proof of concept, written fairly in a fairly verbose way so not
97 very optimised. Took off way more than I expected it would and gathered a lot of
98 community support.
99
100 Feedback/Todo
101 =============
102
103 If you have a read through the source for Pipal you'll notice that it isn't very
104 efficient at the moment. The way I built it was to try to keep each chunk of
105 stats together as a distinct group so that if I wanted to add a new, similar,
106 group then it was easy to just copy and paste the group. Now I've got a working
107 app and I know roughly what I need in the different group types I've got an idea
108 on how to rewrite the main parser to make it much more efficient and hopefully
109 multi-threaded which should speed up the processing by a lot for large lists.
110
111 I could have made these changes before releasing version 1.0 but I figured
112 before I do I want to get as much feedback as possible from users about the
113 features already implemented and about any new features they would like to see
114 so that I can bundle all these together into version 2. So, please get in touch
115 if there is a set of stats that you'd like to see included.
116
117 One other thing I know needs fixing, Pipal doesn't handle certain character
118 encodings very well. If anyone knows how to correctly deal with different
119 encoding types, especially with regards to regular expressions, please let me
120 know.
121
122 Licence
123 =======
124 This project released under the Creative Commons Attribution-Share Alike 2.0
125 UK: England & Wales
126
127 ( http://creativecommons.org/licenses/by-sa/2.0/uk/ )
0 # This is a slightly modified version of the HorizBar script taken from
1 # https://blogs.oracle.com/realneel/entry/ascii_graphs_using_ruby
2
3 class HorizBar
4 WIDTH = 72
5 HEIGHT = 16
6 attr :output_file, true
7
8 def initialize(array)
9 @values = array
10 @output_file = STDOUT
11 end
12
13 def draw
14 #Adjust X axis when there are more than WIDTH cols
15 if @values.length > WIDTH then
16 old_values = @values;
17 @values = []
18 0.upto(WIDTH - 1){ |i| @values << old_values[i*old_values.length/WIDTH]}
19 end
20
21 max = 0
22 @values.each do |val|
23 if !val.nil? and max < val
24 max = val
25 end
26 end
27 # can't use this as the array can have nil's in it
28 # and max can't cope with that
29 # max = @values.max
30 if max == 0
31 return
32 end
33
34 # initialize display with blanks
35 display = Array.new(HEIGHT).collect { Array.new(WIDTH, ' ') }
36 @values.each_with_index do |e, i|
37 f = (e.nil?)?0:e
38
39 num= f*HEIGHT/max
40 (HEIGHT - 1).downto(HEIGHT - 1 - num){|j| display[j][i] = '|'}
41 end
42 display.each{|ar| ar.each{|e| @output_file.putc e}; @output_file.puts "\n"} #now print
43
44 no_of_digits = (@values.length - 1).to_s.length
45 0.upto(no_of_digits) do |digit_number|
46 0.upto(@values.length - 1) do |x|
47 @output_file.print sprintf("%0#{no_of_digits}d", x)[digit_number]
48 end
49 @output_file.puts
50 end
51 end
52 end
0 #!/usr/bin/env ruby
1
2 # == Pipal: Statistical analysis on password dumps
3 #
4 # == Usage
5 #
6 # Usage: pipal [OPTION] ... FILENAME
7 # --help, -h: show help
8 # --top, -t X: show the top X results (default 10)
9 # --output, -o <filename>: output to file
10 # --external, -e <filename>: external file to compare words against
11 # --gkey <Google Maps API key>: to allow zip code lookups (optional)
12 #
13 # FILENAME: The file to count
14 #
15 # Author:: Robin Wood ([email protected])
16 # Copyright:: Copyright (c) Robin Wood 2011
17 # Licence:: Creative Commons Attribution-Share Alike 2.0
18 # Speedbumped by Stefan Venken ([email protected])
19 #
20
21 require 'benchmark'
22 require 'getoptlong'
23 require'net/http'
24 require'uri'
25 require'json'
26 require_relative './horizbar'
27 require_relative './progressbar'
28 require_relative './us_area_codes.rb'
29
30 # Place your google API key here
31 # For more info on getting a key see here https://developers.google.com/maps/documentation/javascript/tutorial#api_key
32 # If you want to leave this blank and pass the key on the command line you can use the --gkey option
33 # From experiments it looks like you don't actually need a valid key but better to have one just in case
34 GOOGLE_API_KEY=''
35
36 if RUBY_VERSION =~ /1\.8/
37 puts "Sorry, Pipal only works correctly on Ruby 1.9.x."
38 puts
39 exit
40 end
41
42 trap("SIGINT") { throw :ctrl_c }
43
44 time = Benchmark.measure do
45
46 days_ab = {'mon' => 0, 'tues' => 0, 'wed' => 0, 'thurs' => 0, 'fri' => 0, 'sat' => 0, 'sun' => 0}
47 months_ab = {"jan" => 0, "feb" => 0, "mar" => 0, "apr" => 0, "may" => 0, "jun" => 0, "jul" => 0, "aug" => 0, "sept" => 0, "oct" => 0, "nov" => 0, "dec" => 0}
48
49 colours = {"black" => 0, "blue" => 0, "brown" => 0, "gray" => 0, "green" => 0, "orange" => 0, "pink" => 0, "purple" => 0, "red" => 0, "white" => 0, "yellow" => 0, 'violet' => 0, 'indigo' => 0}
50 days = {'monday' => 0, 'tuesday' => 0, 'wednesday' => 0, 'thursday' => 0, 'friday' => 0, 'saturday' => 0, 'sunday' => 0}
51 months = {"january" => 0, "february" => 0, "march" => 0, "april" => 0, "may" => 0, "june" => 0, "july" => 0, "august" => 0, "september" => 0, "october" => 0, "november" => 0, "december" => 0}
52
53 char_stats = {
54 "loweralpha" => {'regex' => /^[a-z]+$/, "count" => 0},
55 "upperalpha" => {'regex' => /^[A-Z]+$/, "count" => 0},
56 "numeric" => {'regex' => /^[0-9]+$/, "count" => 0},
57 "special" => {'regex' => /^[\p{Punct}]+$/, "count" => 0},
58
59 "loweralphanum" => {'regex' => /^[a-z0-9]+$/, "count" => 0},
60 "upperalphanum" => {'regex' => /^[A-Z0-9]+$/, "count" => 0},
61 "mixedalpha" => {'regex' => /^[a-zA-Z]+$/, "count" => 0},
62 "loweralphaspecial" => {'regex' => /^[a-z\p{Punct}]+$/, "count" => 0},
63 "upperalphaspecial" => {'regex' => /^[A-Z\p{Punct}]+$/, "count" => 0},
64 "specialnum" => {'regex' => /^[\p{Punct}0-9]+$/, "count" => 0},
65
66 "mixedalphanum" => {'regex' => /^[a-zA-Z0-9]+$/, "count" => 0},
67 "loweralphaspecialnum" => {'regex' => /^[a-z\p{Punct}0-9]+$/, "count" => 0},
68 "mixedalphaspecial" => {'regex' => /^[A-Za-z\p{Punct}]+$/, "count" => 0},
69 "upperalphaspecialnum" => {'regex' => /^[A-Z\p{Punct}0-9]+$/, "count" => 0},
70
71 "mixedalphaspecialnum" => {'regex' => /^[A-Za-z\p{Punct}0-9]+$/, "count" => 0},
72 }
73
74 char_sets_ordering = {
75 "stringdigit" => {"regex" => /^[a-z]+[0-9]+$/, "count" => 0},
76 "allstring" => {"regex" => /^[a-z]+$/, "count" => 0},
77 "digitstring" => {"regex" => /^[0-9]+[a-z]+$/, "count" => 0},
78 "stringdigitstring" => {"regex" => /^[a-z]+[0-9]+[a-z]+$/, "count" => 0},
79 "alldigit" => {"regex" => /^[0-9]+$/, "count" => 0},
80 "digitstringdigit" => {"regex" => /^[0-9]+[a-z]+[0-9]+$/, "count" => 0},
81 "stringspecialdigit" => {"regex" => /^[a-z]+[\p{Punct}]+[0-9]+$/, "count" => 0},
82 "stringspecialstring" => {"regex" => /^[a-z]+[\p{Punct}]+[a-z]+$/, "count" => 0},
83 "stringspecial" => {"regex" => /^[a-z]+[\p{Punct}]+$/, "count" => 0},
84 "specialstring" => {"regex" => /^[\p{Punct}]+[a-z]+$/, "count" => 0},
85 "specialstringspecial" => {"regex" => /^[\p{Punct}]+[a-z]+[\p{Punct}]+$/, "count" => 0},
86 "allspecial" => {"regex" => /^[\p{Punct}]+$/, "count" => 0},
87 "othermask" => {"regex" => /^.*$/, "count" => 0}
88 }
89
90 hashcat_masks = {}
91
92 words = {}
93 total_lines = 0
94
95 one_to_six_chars = 0
96 one_to_eight_chars = 0
97 over_eight_chars = 0
98 #only_lower_alpha_chars = 0
99 #only_upper_alpha_chars = 0
100 #only_numeric_chars = 0
101
102 first_cap_last_num = 0
103 first_cap_last_num_re = /^[A-Z].*[0-9]$/
104 first_cap_last_symbol = 0
105 first_cap_last_symbol_re = /^[A-Z].*[\p{Punct}]$/
106
107 years = {}
108
109 1975.upto(2020) do |year|
110 years[year] = 0
111 end
112
113 # this is the count of words with 1, 2 and 3 numbers on the end
114 #strict_last_on_end = [0,0,0,0,0]
115 singles_on_end_re = /[^0-9]+([0-9]{1})$/
116 singles_on_end = 0
117 doubles_on_end_re = /[^0-9]+([0-9]{2})$/
118 doubles_on_end = 0
119 triples_on_end_re =/[^0-9]+([0-9]{3})$/
120 triples_on_end = 0
121
122 # this is the actual last number on the end, single digit
123 last_on_end = []
124 0.upto(4) do |no_of_digits|
125 last_on_end[no_of_digits] = {}
126 end
127
128 # last two and three numbers on the end
129 last_two_on_end = {}
130 last_three_on_end = {}
131
132 def lookup_by_zipcode(zip, key)
133 geocoder = "http://maps.google.com/maps/geo?q="
134 apikey = "&key=" + key
135
136 # Since the zipcode goes directly into the URL request it needs to be cleaned up.
137 request = geocoder + URI::encode(zip + ', USA') + apikey
138 resp = Net::HTTP.get_response(URI.parse(request))
139
140 data = JSON.parse(resp.body)
141
142 if data.has_key?('Status')
143 # puts "status: " + data['Status']['code'].to_s
144
145 if (data.has_key?('Placemark') and data['Placemark'].length > 0)
146 #puts data['Placemark'][0].inspect
147 # puts "location: " + data['Placemark'][0]['address']
148
149 if data['Placemark'][0].has_key? 'AddressDetails' and
150 data['Placemark'][0]['AddressDetails'].has_key? 'Country' and
151 data['Placemark'][0]['AddressDetails']['Country'].has_key? 'AdministrativeArea' and
152 data['Placemark'][0]['AddressDetails']['Country']['AdministrativeArea'].has_key? 'Locality' and
153 data['Placemark'][0]['AddressDetails']['Country']['AdministrativeArea']['Locality'].has_key? 'PostalCode' and
154 data['Placemark'][0]['AddressDetails']['Country']['AdministrativeArea']['Locality']['PostalCode'].has_key? 'PostalCodeNumber' and
155 data['Placemark'][0]['AddressDetails']['Country'].has_key? 'CountryName'
156
157 # puts "Location: " + data['Placemark'][0]['AddressDetails']['Country']['CountryName']
158 # puts "Location: " + data['Placemark'][0]['AddressDetails']['Country']['AdministrativeArea']['Locality']['PostalCode']['PostalCodeNumber']
159 if data['Placemark'][0]['AddressDetails']['Country']['CountryName'] == 'USA' and data['Placemark'][0]['AddressDetails']['Country']['AdministrativeArea']['Locality']['PostalCode']['PostalCodeNumber'] == zip
160 return data['Placemark'][0]['address']
161 end
162 end
163
164 # return data['Placemark'][0]['address']
165 end
166 end
167
168 return nil
169 end
170
171 class String
172 def is_numeric?
173 Integer self rescue false
174 end
175 end
176
177 def is_numeric val
178 return val.to_s =~ /^[0-9]+$/
179 end
180
181 opts = GetoptLong.new(
182 [ '--help', '-h', "-?", GetoptLong::NO_ARGUMENT ],
183 [ '--top', "-t" , GetoptLong::REQUIRED_ARGUMENT ],
184 [ '--output', "-o" , GetoptLong::REQUIRED_ARGUMENT ],
185 [ '--external', "-e" , GetoptLong::REQUIRED_ARGUMENT ],
186 [ '--gkey', GetoptLong::REQUIRED_ARGUMENT ],
187 [ "-v" , GetoptLong::NO_ARGUMENT ]
188 )
189
190 # Display the usage
191 def usage
192 puts"pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
193
194 Usage: pipal [OPTION] ... FILENAME
195 --help, -h: show help
196 --top, -t X: show the top X results (default 10)
197 --output, -o <filename>: output to file
198 --external, -e <filename>: external file to compare words against
199 --gkey <Google Maps API key>: to allow zip code lookups (optional)
200
201 FILENAME: The file to count
202
203 "
204 exit
205 end
206
207 cap_at = 10
208 output_file = STDOUT
209 external_list = {}
210 google_maps_api_key = GOOGLE_API_KEY
211
212 begin
213 opts.each do |opt, arg|
214 case opt
215 when '--help'
216 usage
217 when "--top"
218 if arg.is_numeric?
219 cap_at = arg.to_i
220 if cap_at <= 0
221 puts"pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
222
223 Please enter a positive number of lines
224
225 "
226 exit 1
227 end
228 else
229 puts"pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
230
231 Invalid number of lines
232
233 "
234 exit 1
235 end
236 when "--gkey"
237 google_maps_api_key = arg
238 when "--external"
239 if File.exist?(arg)
240 begin
241 File.open(arg, 'r').each_line do |word|
242 external_list[word.force_encoding("ASCII-8BIT").strip] = 0 unless word.force_encoding("ASCII-8BIT").strip == ''
243 end
244 rescue Errno::EACCES => e
245 puts"pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
246
247 Unable to open external file
248
249 "
250 exit 1
251 end
252 else
253 puts"pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
254
255 Unable to find external file
256
257 "
258 exit 1
259 end
260 when "--output"
261 begin
262 output_file = File.new(arg, "w")
263 rescue Errno::EACCES => e
264 puts"pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
265
266 Unable to open output file
267
268 "
269 exit 1
270 end
271 end
272 end
273 rescue GetoptLong::InvalidOption => e
274 puts
275 usage
276 exit
277 rescue => e
278 puts "Something went wrong, please report it to [email protected] along with these messages:"
279 puts
280 puts e.message
281 puts
282 puts e.class.to_s
283 puts
284 puts "Backtrace:"
285 puts e.backtrace
286 puts
287 usage
288 exit 1
289 end
290
291 if ARGV.length != 1
292 puts"pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
293
294 Please specify the file to count
295
296 "
297 exit 1
298 end
299
300 filename = ARGV.shift
301
302 if !File.exist? filename
303 puts"pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
304
305 Can't find the password file
306
307 "
308 exit 2
309 end
310
311 lengths = []
312 max_length = 0
313 base_words = {}
314
315 puts "Generating stats, hit CTRL-C to finish early and dump stats on words already processed."
316 puts "Please wait..."
317
318 if %x{wc -l '#{filename}'}.match(/\s*([0-9]+).*/)
319 file_line_count = $1.to_i
320 else
321 filesize = File.stat(filename).size
322 file_line_count = (filesize / 8).to_i
323 puts "Can't find wc to calculate the number of lines so guessing as " + file_line_count.to_s + " based on file size"
324 end
325
326 pbar = ProgressBar.new("Processing", file_line_count)
327
328 catch :ctrl_c do
329 begin
330 File.open(filename, "r").each_line do |line|
331 begin
332 line.strip!
333 if line == ""
334 pbar.inc
335 next
336 end
337 # Doing this so that I can support a wider range of characters, a UK pound sign
338 # breaks the app without it
339 line.force_encoding("ASCII-8BIT")
340 lower_line = line.downcase
341
342 if !words.has_key?(line)
343 words[line] = 0
344 end
345 words[line] += 1
346
347 # strip any non-alpha from the start or end, I was going to strip all non-alpha
348 # but then found a list with Unc0rn as a very common base. Stripping all non-alpha
349 # would leave with Uncrn which doesn't really make any sense as without the 133t speak
350 # it is out of context.
351 #
352 # If you want all non-alpha stripped use the following line instead
353 #
354 # word_just_alpha = lower_line.gsub(/[^a-z]*/, "")
355 #
356 word_just_alpha = lower_line.gsub(/^[^a-z]*/, "").gsub(/[^a-z]*$/, '')
357 if word_just_alpha.length > 3
358 if !base_words.has_key?(word_just_alpha)
359 base_words[word_just_alpha] = 0
360 end
361 base_words[word_just_alpha] += 1
362 end
363
364 if lengths[line.length].nil?
365 lengths[line.length] = 0
366 end
367 lengths[line.length] += 1
368
369 # if line.length > max_length
370 # max_length = line.length
371 # end
372
373 if line.length < 9
374 one_to_eight_chars += 1
375 end
376
377 if line.length < 7
378 one_to_six_chars += 1
379 end
380
381 if line.length > 8
382 over_eight_chars += 1
383 end
384
385 # Replaced with character set upperalpha
386 # if line. =~ /^[A-Z]*$/
387 # only_upper_alpha_chars += 1
388 # end
389
390 # Replaced with character set loweralpha
391 # if line. =~ /^[a-z]*$/
392 # only_lower_alpha_chars += 1
393 # end
394
395 # Replaced with character set alldigit
396 # if line. =~ /^[0-9]*$/
397 # only_numeric_chars += 1
398 # end
399
400 if line =~ first_cap_last_symbol_re
401 first_cap_last_symbol += 1
402 end
403
404 if line =~ first_cap_last_num_re
405 first_cap_last_num += 1
406 end
407
408 years.each_pair do |year, count|
409 if /#{year}/.match line
410 years[year] += 1
411 end
412 end
413
414 days_ab.each_pair do |day, count|
415 if /#{day}/i.match line
416 days_ab[day] += 1
417 end
418 end
419
420 months_ab.each_pair do |month, count|
421 if /#{month}/i.match line
422 months_ab[month] += 1
423 end
424 end
425
426 colours.each_pair do |colour, count|
427 if /#{colour}/i.match line
428 colours[colour] += 1
429 end
430 end
431
432 days.each_pair do |day, count|
433 if /#{day}/i.match line
434 days[day] += 1
435 end
436 end
437
438 months.each_pair do |month, count|
439 if /#{month}/i.match line
440 months[month] += 1
441 end
442 end
443
444 external_list.each_pair do |domain, count|
445 if /#{Regexp.quote(domain)}/i.match line
446 external_list[domain] += 1
447 end
448 end
449
450 #if line =~ /[^0-9]+([0-9]{1})$/
451 # if /[^0-9]+([0-9]{1})$/.match line
452 if singles_on_end_re.match line
453 singles_on_end += 1
454 end
455
456 # Can't merge these two as the first is strict, 2 digits on the end, the second
457 # just wants the last two digits regardless
458 # if /[^0-9]+([0-9]{2})$/.match line
459 if doubles_on_end_re.match line
460 # if line =~ /[^0-9]+([0-9]{2})$/
461 doubles_on_end += 1
462 end
463
464 # if /[^0-9]+([0-9]{3})$/.match line
465 if triples_on_end_re.match line
466 #if line =~ /[^0-9]+([0-9]{3})$/
467 triples_on_end += 1
468 end
469
470 1.upto(5) do |no_of_digits|
471 if /([0-9]{#{no_of_digits}})$/.match line
472 last_numbers = $1
473 if !last_on_end[no_of_digits - 1].has_key?(last_numbers)
474 last_on_end[no_of_digits - 1][last_numbers] = 0
475 end
476 last_on_end[no_of_digits - 1][last_numbers] += 1
477 end
478 # if /[^0-9]+([0-9]{#{no_of_digits}})$/.match line
479 # strict_last_on_end[no_of_digits - 1] += 1
480 # end
481
482 end
483
484 # numbers_on_end.each_pair do |number, count|
485 # if /[^0-9]*#{number}$/.match line
486 # numbers_on_end[number] += 1
487 # end
488 # end
489
490 char_stats.each_pair do |name, data|
491 begin
492 if line =~ data['regex']
493 char_stats[name]['count'] += 1
494 break
495 end
496 rescue Encoding::CompatibilityError
497 puts "Encoding problem found with password: " + line
498 end
499 end
500
501 char_sets_ordering.each_pair do |name, data|
502 begin
503 if lower_line =~ data['regex']
504 char_sets_ordering[name]['count'] += 1
505 break
506 end
507 rescue Encoding::CompatibilityError
508 puts "Encoding problem found with password: " + line
509 end
510 end
511
512 # This won't work as the special replacement hits all the previous ?'s that have been replaced,
513 # lower at the end would do the same with all the characters so can't use the order to fix this problem
514 # mask_line = line.gsub(/[a-z]/, "?l").gsub(/[A-Z]/,'?u').gsub(/[0-9]/, '?d').gsub(/[\p{Punct}]/, '?s')
515 mask_line = ""
516 line.each_char do |char|
517 case char
518 when /[a-z]/
519 mask_line << "?l"
520 when /[A-Z]/
521 mask_line << "?u"
522 when /[0-9]/
523 mask_line << "?d"
524 else
525 mask_line << "?s"
526 end
527 end
528
529 if !hashcat_masks.has_key? mask_line
530 hashcat_masks[mask_line] = {'count' => 0}
531 end
532 hashcat_masks[mask_line]['count'] += 1
533
534 pbar.inc
535
536 total_lines += 1
537 rescue ArgumentError => e
538 puts "Encoding problem processing word: " + line
539 pbar.inc
540 rescue => e
541 puts "Something went wrong, please report it to [email protected] along with these messages:"
542 puts
543 puts e.message
544 puts
545 puts e.class.to_s
546 puts
547 puts "Backtrace:"
548 puts e.backtrace
549 puts
550 usage
551 exit 1
552 end
553 end
554 rescue Errno::EACCES => e
555 puts"pipal 2.0 Robin Wood ([email protected]) (www.digininja.org)
556
557 Unable to open the password file
558
559 "
560 exit 1
561 rescue => e
562 puts "Something went wrong, please report it to [email protected] along with these messages:"
563 puts
564 puts e.message
565 puts
566 puts e.class.to_s
567 puts
568 puts "Backtrace:"
569 puts e.backtrace
570 puts
571 usage
572 exit 1
573 end
574 end
575
576 pbar.halt
577
578 # This is a screen puts to clear after the status bars in case the data is being written to the screen, do not add outfile to it
579 puts
580 puts
581
582 output_file.puts "Total entries = " + total_lines.to_s
583 uniq_words = words.to_a.uniq
584 output_file.puts "Total unique entries = " + uniq_words.length.to_s
585 uniq_words = Array.new(words.to_a.uniq)
586
587 output_file.puts
588 output_file.puts "Top " + cap_at.to_s + " passwords"
589 # The default is to sort lowest to highest, the -1 just inverts that
590 words.sort{|a,b| (a[1]<=>b[1]) * -1}[0, cap_at].each { |elem|
591 percentage = (elem[1].to_f / total_lines) * 100
592 output_file.puts elem[0] + " = " + elem[1].to_s + " (" + percentage.round(2).to_s + "%)"
593 }
594
595 output_file.puts
596 output_file.puts "Top " + cap_at.to_s + " base words"
597 base_words.sort{|a,b| (a[1]<=>b[1]) * -1}[0, cap_at].each { |elem|
598 percentage = (elem[1].to_f / total_lines) * 100
599 output_file.puts elem[0] + " = " + elem[1].to_s + " (" + percentage.round(2).to_s + "%)"
600 }
601
602 output_file.puts
603 output_file.puts "Password length (length ordered)"
604
605 length_ordered = []
606 0.upto(lengths.count) do |len|
607 if lengths[len].nil?
608 lengths[len] = 0
609 end
610 percentage = ((lengths[len].to_f / total_lines) * 100)
611 output_file.puts len.to_s + ' = ' + lengths[len].to_s + " (" + percentage.round(2).to_s + "%)" if lengths[len] > 0
612
613 pair = [len, lengths[len], percentage]
614 length_ordered << pair
615 end
616
617 length_ordered.sort! do |x,y|
618 y[1] <=> x[1]
619 end
620
621 output_file.puts
622 output_file.puts "Password length (count ordered)"
623 length_ordered.each do |pair|
624 output_file.puts pair[0].to_s + " = " + pair[1].to_s + " (" + pair[2].round(2).to_s + "%)" if pair[1] > 0
625 end
626
627 output_file.puts
628
629 horiz = HorizBar.new(lengths)
630 horiz.output_file = output_file
631 horiz.draw
632
633 output_file.puts "One to six characters = " + one_to_six_chars.to_s + ' (' + ((one_to_six_chars.to_f/total_lines) * 100).round(2).to_s + '%)'
634 output_file.puts "One to eight characters = " + one_to_eight_chars.to_s + ' (' + ((one_to_eight_chars.to_f/total_lines) * 100).round(2).to_s + '%)'
635 output_file.puts "More than eight characters = " + over_eight_chars.to_s + ' (' + ((over_eight_chars.to_f/total_lines) * 100).round(2).to_s + '%)'
636
637 output_file.puts
638
639 output_file.puts "Only lowercase alpha = " + char_stats['loweralpha']['count'].to_s + ' (' + ((char_stats['loweralpha']['count'].to_f/total_lines) * 100).round(2).to_s + '%)'
640 output_file.puts "Only uppercase alpha = " + char_stats['upperalpha']['count'].to_s + ' (' + ((char_stats['upperalpha']['count'].to_f/total_lines) * 100).round(2).to_s + '%)'
641 output_file.puts "Only alpha = " + (char_stats['upperalpha']['count'] + char_stats['loweralpha']['count']).to_s + ' (' + (((char_stats['upperalpha']['count'] + char_stats['loweralpha']['count']).to_f/total_lines) * 100).round(2).to_s + '%)'
642
643 output_file.puts "Only numeric = " + char_stats['numeric']['count'].to_s + ' (' + ((char_stats['numeric']['count'].to_f/total_lines) * 100).round(2).to_s + '%)'
644
645 output_file.puts
646 output_file.puts "First capital last symbol = " + first_cap_last_symbol.to_s + ' (' + ((first_cap_last_symbol.to_f/total_lines) * 100).round(2).to_s + '%)'
647 output_file.puts "First capital last number = " + first_cap_last_num.to_s + ' (' + ((first_cap_last_num.to_f/total_lines) * 100).round(2).to_s + '%)'
648
649 if external_list.length > 0
650 count_ordered = []
651 external_list.each_pair do |domain, count|
652 count_ordered << [domain, count] unless count == 0
653 end
654 external_list = count_ordered.sort do |x,y|
655 (x[1] <=> y[1]) * -1
656 end
657
658 output_file.puts
659 output_file.puts "External list (Top " + cap_at.to_s + ")"
660 disp = false
661 external_list[0, cap_at].each do |data|
662 disp = true
663 output_file.puts data[0] + " = " + data[1].to_s + ' (' + ((data[1].to_f/total_lines) * 100).round(2).to_s + '%)'
664 end
665 unless disp
666 output_file.puts "None found"
667 end
668 end
669
670 output_file.puts
671 output_file.puts "Months"
672 disp = false
673 months.each_pair do |month, count|
674 unless count == 0
675 disp = true
676 output_file.puts month + " = " + count.to_s + ' (' + ((count.to_f/total_lines) * 100).round(2).to_s + '%)'unless count == 0
677 end
678 end
679 unless disp
680 output_file.puts "None found"
681 end
682
683 output_file.puts
684 output_file.puts "Days"
685 disp = false
686 days.each_pair do |day, count|
687 unless count == 0
688 disp = true
689 output_file.puts day + " = " + count.to_s + ' (' + ((count.to_f/total_lines) * 100).round(2).to_s + '%)' unless count == 0
690 end
691 end
692 unless disp
693 output_file.puts "None found"
694 end
695
696 output_file.puts
697 output_file.puts "Months (Abreviated)"
698 disp = false
699 months_ab.each_pair do |month, count|
700 unless count == 0
701 disp = true
702 output_file.puts month + " = " + count.to_s + ' (' + ((count.to_f/total_lines) * 100).round(2).to_s + '%)' unless count == 0
703 end
704 end
705 unless disp
706 output_file.puts "None found"
707 end
708
709 output_file.puts
710 output_file.puts "Days (Abreviated)"
711 disp = false
712 days_ab.each_pair do |day, count|
713 unless count == 0
714 disp = true
715 output_file.puts day + " = " + count.to_s + ' (' + ((count.to_f/total_lines) * 100).round(2).to_s + '%)' unless count == 0
716 end
717 end
718 unless disp
719 output_file.puts "None found"
720 end
721
722 output_file.puts
723 output_file.puts "Includes years"
724 disp = false
725 years.each_pair do |number, count|
726 unless count == 0
727 disp = true
728 output_file.puts number.to_s + " = " + count.to_s + ' (' + ((count.to_f/total_lines) * 100).round(2).to_s + '%)'unless count == 0
729 end
730 end
731 unless disp
732 output_file.puts "None found"
733 end
734
735 count_ordered = []
736 years.each_pair do |year, count|
737 count_ordered << [year, count] unless count == 0
738 end
739 years = count_ordered.sort do |x,y|
740 (x[1] <=> y[1]) * -1
741 end
742
743 output_file.puts
744 output_file.puts "Years (Top " + cap_at.to_s + ")"
745 disp = false
746 years[0, cap_at].each do |data|
747 disp = true
748 output_file.puts data[0].to_s + " = " + data[1].to_s + ' (' + ((data[1].to_f/total_lines) * 100).round(2).to_s + '%)'
749 end
750 unless disp
751 output_file.puts "None found"
752 end
753
754 output_file.puts
755 output_file.puts "Colours"
756 disp = false
757 colours.each_pair do |colour, count|
758 unless count == 0
759 disp = true
760 output_file.puts colour + " = " + count.to_s + ' (' + ((count.to_f/total_lines) * 100).round(2).to_s + '%)' unless count == 0
761 end
762 end
763 unless disp
764 output_file.puts "None found"
765 end
766
767
768 output_file.puts
769
770 #output_file.puts "Single digit on the end = " + strict_last_on_end[2].count.to_s + ' (' + ((strict_last_on_end[0].count.to_f/total_lines) * 100).round(2).to_s + '%)'
771 #output_file.puts "Two digits on the end = " + strict_last_on_end[2].count.to_s + ' (' + ((strict_last_on_end[1].count.to_f/total_lines) * 100).round(2).to_s + '%)'
772 #output_file.puts "Three digits on the end = " + strict_last_on_end[2].count.to_s + ' (' + ((strict_last_on_end[2].count.to_f/total_lines) * 100).round(2).to_s + '%)'
773
774 output_file.puts "Single digit on the end = " + singles_on_end.to_s + ' (' + ((singles_on_end.to_f/total_lines) * 100).round(2).to_s + '%)'
775 output_file.puts "Two digits on the end = " + doubles_on_end.to_s + ' (' + ((doubles_on_end.to_f/total_lines) * 100).round(2).to_s + '%)'
776 output_file.puts "Three digits on the end = " + triples_on_end.to_s + ' (' + ((triples_on_end.to_f/total_lines) * 100).round(2).to_s + '%)'
777
778 output_file.puts
779 output_file.puts "Last number"
780 disp = false
781
782 graph_numbers = {0=>0, 1=>0, 2=>0, 3=>0, 4=>0, 5=>0, 6=>0, 7=>0, 8=>0, 9=>0}
783
784 c = last_on_end[0].to_a.sort do |x,y|
785 (x[0] <=> y[0])
786 end
787
788 c.each do |number, count|
789 unless count == 0
790 disp = true
791 output_file.puts number.to_s + " = " + count.to_s + ' (' + ((count.to_f/total_lines) * 100).round(2).to_s + '%)' unless count == 0
792 end
793 graph_numbers[number.to_i] = count
794 end
795 unless disp
796 output_file.puts "None found"
797 end
798
799 output_file.puts
800 horiz = HorizBar.new(graph_numbers.values)
801 horiz.output_file = output_file
802 horiz.draw
803
804 area_codes = []
805 zip_codes = []
806
807 digit_number = 0
808 last_on_end.each do |a|
809 c = a.to_a.sort do |x,y|
810 (x[1] <=> y[1]) * -1
811 end
812
813 digit_number += 1
814 if c.count > 0
815 if (digit_number == 1)
816 output_file.puts "Last digit"
817 else
818 output_file.puts "Last " + digit_number.to_s + " digits (Top " + cap_at.to_s + ")"
819 end
820
821 c[0, cap_at].each do |d|
822 output_file.puts d[0] + " = " + d[1].to_s + ' (' + ((d[1].to_f/total_lines) * 100).round(2).to_s + '%)'
823
824 if digit_number == 3
825 area_codes << d[0]
826 end
827 if digit_number == 5
828 zip_codes << d[0]
829 end
830 end
831 output_file.puts
832 end
833 end
834
835 count_ordered = []
836 char_stats.each_pair do |name, data|
837 count_ordered << [name, data] unless data['count'] == 0
838 end
839 char_stats = count_ordered.sort do |x,y|
840 (x[1]['count'] <=> y[1]['count']) * -1
841 end
842
843 areas = {}
844 area_codes.each do |code|
845 code = code.to_s
846 if US_area_codes.has_key? code
847 area = US_area_codes[code]
848 areas[code] = area
849 end
850 end
851 if areas.length > 0
852 output_file.puts "US Area Codes"
853 areas.each_pair do |code, area|
854 output_file.puts code + ' = ' + area[1] + " (" + area[0] + ")"
855 end
856 output_file.puts
857 end
858
859 if google_maps_api_key != ""
860 areas = {}
861 zip_codes.each do |zip|
862 area = lookup_by_zipcode zip.to_s, google_maps_api_key
863 unless area.nil?
864 areas[zip] = area
865 end
866 end
867 if areas.length > 0
868 output_file.puts "US Zip Codes"
869 areas.each_pair do |zip, area|
870 output_file.puts zip + ' = ' + area
871 end
872 output_file.puts
873 end
874 end
875
876 output_file.puts "Character sets"
877 char_stats.each do |name, data|
878 output_file.puts name + ": " + data['count'].to_s + " (" + ((data['count'].to_f/total_lines) * 100).round(2).to_s + "%)"
879 end
880
881 count_ordered = []
882 char_sets_ordering.each_pair do |name, data|
883 count_ordered << [name, data] unless data['count'] == 0
884 end
885 char_sets_ordering = count_ordered.sort do |x,y|
886 (x[1]['count'] <=> y[1]['count']) * -1
887 end
888
889 output_file.puts
890 output_file.puts "Character set ordering"
891 char_sets_ordering.each do |name, data|
892 output_file.puts name + ": " + data['count'].to_s + " (" + ((data['count'].to_f/total_lines) * 100).round(2).to_s + "%)"
893 end
894
895 count_ordered = []
896 hashcat_masks.each_pair do |name, data|
897 count_ordered << [name, data] unless data['count'] == 0
898 end
899 hashcat_masks = count_ordered.sort do |x,y|
900 (x[1]['count'] <=> y[1]['count']) * -1
901 end
902
903 output_file.puts
904 output_file.puts "Hashcat masks (Top " + cap_at.to_s + ")"
905 hashcat_masks[0, cap_at].each do |name, data|
906 output_file.puts name + ": " + data['count'].to_s + " (" + ((data['count'].to_f/total_lines) * 100).round(2).to_s + "%)"
907 end
908
909 end
910 puts time if false
0 #
1 # Ruby/ProgressBar - a text progress bar library
2 #
3 # Copyright (C) 2001-2005 Satoru Takabayashi <[email protected]>
4 # All rights reserved.
5 # This is free software with ABSOLUTELY NO WARRANTY.
6 #
7 # You can redistribute it and/or modify it under the terms
8 # of Ruby's license.
9 #
10
11 class ProgressBar
12 VERSION = "0.9"
13
14 def initialize (title, total, out = STDERR)
15 @title = title
16 @total = total
17 @out = out
18 @terminal_width = 80
19 @bar_mark = "o"
20 @current = 0
21 @previous = 0
22 @finished_p = false
23 @start_time = Time.now
24 @previous_time = @start_time
25 @title_width = 14
26 @format = "%-#{@title_width}s %3d%% %s %s"
27 @format_arguments = [:title, :percentage, :bar, :stat]
28 clear
29 show
30 end
31 attr_reader :title
32 attr_reader :current
33 attr_reader :total
34 attr_accessor :start_time
35
36 private
37 def fmt_bar
38 bar_width = do_percentage * @terminal_width / 100
39 sprintf("|%s%s|",
40 @bar_mark * bar_width,
41 " " * (@terminal_width - bar_width))
42 end
43
44 def fmt_percentage
45 do_percentage
46 end
47
48 def fmt_stat
49 if @finished_p then elapsed else eta end
50 end
51
52 def fmt_stat_for_file_transfer
53 if @finished_p then
54 sprintf("%s %s %s", bytes, transfer_rate, elapsed)
55 else
56 sprintf("%s %s %s", bytes, transfer_rate, eta)
57 end
58 end
59
60 def fmt_title
61 @title[0,(@title_width - 1)] + ":"
62 end
63
64 def convert_bytes (bytes)
65 if bytes < 1024
66 sprintf("%6dB", bytes)
67 elsif bytes < 1024 * 1000 # 1000kb
68 sprintf("%5.1fKB", bytes.to_f / 1024)
69 elsif bytes < 1024 * 1024 * 1000 # 1000mb
70 sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
71 else
72 sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
73 end
74 end
75
76 def transfer_rate
77 bytes_per_second = @current.to_f / (Time.now - @start_time)
78 sprintf("%s/s", convert_bytes(bytes_per_second))
79 end
80
81 def bytes
82 convert_bytes(@current)
83 end
84
85 def format_time (t)
86 t = t.to_i
87 sec = t % 60
88 min = (t / 60) % 60
89 hour = t / 3600
90 sprintf("%02d:%02d:%02d", hour, min, sec);
91 end
92
93 # ETA stands for Estimated Time of Arrival.
94 def eta
95 if @current == 0
96 "ETA: --:--:--"
97 else
98 elapsed = Time.now - @start_time
99 eta = elapsed * @total / @current - elapsed;
100 sprintf("ETA: %s", format_time(eta))
101 end
102 end
103
104 def elapsed
105 elapsed = Time.now - @start_time
106 sprintf("Time: %s", format_time(elapsed))
107 end
108
109 def eol
110 if @finished_p then "\n" else "\r" end
111 end
112
113 def do_percentage
114 if @total.zero?
115 100
116 else
117 @current * 100 / @total
118 end
119 end
120
121 def get_width
122 # FIXME: I don't know how portable it is.
123 default_width = 80
124 begin
125 tiocgwinsz = 0x5413
126 data = [0, 0, 0, 0].pack("SSSS")
127 if @out.ioctl(tiocgwinsz, data) >= 0 then
128 rows, cols, xpixels, ypixels = data.unpack("SSSS")
129 if cols >= 0 then cols else default_width end
130 else
131 default_width
132 end
133 rescue Exception
134 default_width
135 end
136 end
137
138 def show
139 arguments = @format_arguments.map {|method|
140 method = sprintf("fmt_%s", method)
141 send(method)
142 }
143 line = sprintf(@format, *arguments)
144
145 width = get_width
146 if line.length == width - 1
147 @out.print(line + eol)
148 @out.flush
149 elsif line.length >= width
150 @terminal_width = [@terminal_width - (line.length - width + 1), 0].max
151 if @terminal_width == 0 then @out.print(line + eol) else show end
152 else # line.length < width - 1
153 @terminal_width += width - line.length + 1
154 show
155 end
156 @previous_time = Time.now
157 end
158
159 def show_if_needed
160 if @total.zero?
161 cur_percentage = 100
162 prev_percentage = 0
163 else
164 cur_percentage = (@current * 100 / @total).to_i
165 prev_percentage = (@previous * 100 / @total).to_i
166 end
167
168 # Use "!=" instead of ">" to support negative changes
169 if cur_percentage != prev_percentage ||
170 Time.now - @previous_time >= 1 || @finished_p
171 show
172 end
173 end
174
175 public
176 def clear
177 @out.print "\r"
178 @out.print(" " * (get_width - 1))
179 @out.print "\r"
180 end
181
182 def finish
183 @current = @total
184 @finished_p = true
185 show
186 end
187
188 def finished?
189 @finished_p
190 end
191
192 def file_transfer_mode
193 @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
194 end
195
196 def format= (format)
197 @format = format
198 end
199
200 def format_arguments= (arguments)
201 @format_arguments = arguments
202 end
203
204 def halt
205 @finished_p = true
206 show
207 end
208
209 def inc (step = 1)
210 @current += step
211 @current = @total if @current > @total
212 show_if_needed
213 @previous = @current
214 end
215
216 def set (count)
217 if count < 0 || count > @total
218 raise "invalid count: #{count} (total: #{@total})"
219 end
220 @current = count
221 show_if_needed
222 @previous = @current
223 end
224
225 def inspect
226 "#<ProgressBar:#{@current}/#{@total}>"
227 end
228 end
229
230 class ReversedProgressBar < ProgressBar
231 def do_percentage
232 100 - super
233 end
234 end
235
0 US_area_codes = {}
1
2 US_area_codes["201"] = ["NJ","N New Jersey: Jersey City, Hackensack"]
3 US_area_codes["202"] = ["DC","Washington, D.C."]
4 US_area_codes["203"] = ["CT","Connecticut: Fairfield County and New Haven County; Bridgeport, New Haven"]
5 US_area_codes["204"] = ["MB","Canada: Manitoba"]
6 US_area_codes["205"] = ["AL","Central Alabama (including Birmingham)"]
7 US_area_codes["206"] = ["WA","W Washington state: Seattle and Bainbridge Island"]
8 US_area_codes["207"] = ["ME","Maine"]
9 US_area_codes["208"] = ["ID","Idaho"]
10 US_area_codes["209"] = ["CA","Cent. California: Stockton"]
11 US_area_codes["210"] = ["TX","S Texas: San Antonio"]
12 US_area_codes["211"] = ["--","Local community info / referral services"]
13 US_area_codes["212"] = ["NY","New York City, New York"]
14 US_area_codes["213"] = ["CA","S California: Los Angeles"]
15 US_area_codes["214"] = ["TX","Texas: Dallas Metro"]
16 US_area_codes["215"] = ["PA","SE Pennsylvania: Philadelphia"]
17 US_area_codes["216"] = ["OH","Cleveland"]
18 US_area_codes["217"] = ["IL","Cent. Illinois: Springfield"]
19 US_area_codes["218"] = ["MN","N Minnesota: Duluth"]
20 US_area_codes["219"] = ["IN","NW Indiana: Gary"]
21 US_area_codes["224"] = ["IL","Northern NE Illinois: Evanston, Waukegan, Northbrook"]
22 US_area_codes["225"] = ["LA","Louisiana: Baton Rouge, New Roads, Donaldsonville, Albany, Gonzales, Greensburg, Plaquemine, Vacherie"]
23 US_area_codes["226"] = ["ON","Canada: SW Ontario: Windsor"]
24 US_area_codes["228"] = ["MS","S Mississippi"]
25 US_area_codes["229"] = ["GA","SW Georgia: Albany"]
26 US_area_codes["231"] = ["MI","W Michigan: Northwestern portion of lower Peninsula; Traverse City, Muskegon, Cheboygan, Alanson"]
27 US_area_codes["234"] = ["OH","NE Ohio: Canton, Akron"]
28 US_area_codes["236"] = ["VA","Virginia (region unknown) / Unassigned?"]
29 US_area_codes["239"] = ["FL","Florida"]
30 US_area_codes["240"] = ["MD","W Maryland: Silver Spring, Frederick, Gaithersburg"]
31 US_area_codes["242"] = ["--","Bahamas"]
32 US_area_codes["246"] = ["--","Barbados"]
33 US_area_codes["248"] = ["MI","Michigan: Oakland County, Pontiac"]
34 US_area_codes["250"] = ["BC","Canada: British Columbia"]
35 US_area_codes["251"] = ["AL","S Alabama: Mobile and coastal areas, Jackson, Evergreen, Monroeville"]
36 US_area_codes["252"] = ["NC","E North Carolina"]
37 US_area_codes["253"] = ["WA","Washington: South Tier - Tacoma, Federal Way"]
38 US_area_codes["254"] = ["TX","Central Texas"]
39 US_area_codes["256"] = ["AL","E and N Alabama"]
40 US_area_codes["260"] = ["IN","NE Indiana: Fort Wayne"]
41 US_area_codes["262"] = ["WI","SE Wisconsin: counties of Kenosha, Ozaukee, Racine, Walworth, Washington, Waukesha"]
42 US_area_codes["264"] = ["--","Anguilla"]
43 US_area_codes["267"] = ["PA","SE Pennsylvania: Philadelphia"]
44 US_area_codes["268"] = ["--","Antigua and Barbuda"]
45 US_area_codes["269"] = ["MI","SW Michigan: Kalamazoo, Saugatuck, Hastings, Battle Creek, Sturgis to Lake Michigan"]
46 US_area_codes["270"] = ["KY","W Kentucky: Bowling Green, Paducah"]
47 US_area_codes["276"] = ["VA","S and SW Virginia: Bristol, Stuart, Martinsville"]
48 US_area_codes["278"] = ["MI","Michigan"]
49 US_area_codes["281"] = ["TX","Texas: Houston Metro"]
50 US_area_codes["283"] = ["OH","SW Ohio: Cincinnati"]
51 US_area_codes["284"] = ["--","British Virgin Islands"]
52 US_area_codes["289"] = ["ON","Canada: S Cent. Ontario: Greater Toronto Area -- Durham, Halton, Hamilton-Wentworth, Niagara, Peel, York, and southern Simcoe County"]
53 US_area_codes["301"] = ["MD","W Maryland: Silver Spring, Frederick, Camp Springs, Prince George's County"]
54 US_area_codes["302"] = ["DE","Delaware"]
55 US_area_codes["303"] = ["CO","Central Colorado: Denver"]
56 US_area_codes["304"] = ["WV","West Virginia"]
57 US_area_codes["305"] = ["FL","SE Florida: Miami, the Keys"]
58 US_area_codes["306"] = ["SK","Canada: Saskatchewan"]
59 US_area_codes["307"] = ["WY","Wyoming"]
60 US_area_codes["308"] = ["NE","W Nebraska: North Platte"]
61 US_area_codes["309"] = ["IL","W Cent. Illinois: Peoria"]
62 US_area_codes["310"] = ["CA","S California: Beverly Hills, West Hollywood, West Los Angeles"]
63 US_area_codes["311"] = ["--","Reserved for special applications"]
64 US_area_codes["312"] = ["IL","Illinois: Chicago"]
65 US_area_codes["313"] = ["MI","Michigan: Detroit and suburbs"]
66 US_area_codes["314"] = ["MO","SE Missouri: St Louis city and parts of the metro area only"]
67 US_area_codes["315"] = ["NY","N Cent. New York: Syracuse"]
68 US_area_codes["316"] = ["KS","S Kansas: Wichita"]
69 US_area_codes["317"] = ["IN","Cent. Indiana: Indianapolis"]
70 US_area_codes["318"] = ["LA","N Louisiana: Shreveport, Ruston, Monroe, Alexandria"]
71 US_area_codes["319"] = ["IA","E Iowa: Cedar Rapids"]
72 US_area_codes["320"] = ["MN","Cent. Minnesota: Saint Cloud"]
73 US_area_codes["321"] = ["FL","Florida: Brevard County, Cape Canaveral area; Metro Orlando"]
74 US_area_codes["323"] = ["CA","S California: Los Angeles"]
75 US_area_codes["325"] = ["TX","Central Texas: Abilene, Sweetwater, Snyder, San Angelo"]
76 US_area_codes["330"] = ["OH","NE Ohio: Akron, Canton, Youngstown; Mahoning County, parts of Trumbull/Warren counties"]
77 US_area_codes["331"] = ["IL","W NE Illinois, western suburbs of Chicago"]
78 US_area_codes["334"] = ["AL","S Alabama: Auburn/Opelika, Montgomery and coastal areas"]
79 US_area_codes["336"] = ["NC","Cent. North Carolina: Greensboro, Winston-Salem, High Point"]
80 US_area_codes["337"] = ["LA","SW Louisiana: Lake Charles, Lafayette"]
81 US_area_codes["339"] = ["MA","Massachusetts: Boston suburbs, to the south and west"]
82 US_area_codes["340"] = ["VI","US Virgin Islands"]
83 US_area_codes["341"] = ["CA","(overlay on 510; SUSPENDED)"]
84 US_area_codes["345"] = ["--","Cayman Islands"]
85 US_area_codes["347"] = ["NY","New York"]
86 US_area_codes["351"] = ["MA","Massachusetts: north of Boston to NH, 508, and 781"]
87 US_area_codes["352"] = ["FL","Florida: Gainesville area, Ocala, Crystal River"]
88 US_area_codes["360"] = ["WA","W Washington State: Olympia, Bellingham"]
89 US_area_codes["361"] = ["TX","S Texas: Corpus Christi"]
90 US_area_codes["369"] = ["CA","Solano County"]
91 US_area_codes["380"] = ["OH","Ohio: Columbus"]
92 US_area_codes["385"] = ["UT","Utah: Salt Lake City Metro"]
93 US_area_codes["386"] = ["FL","N central Florida: Lake City"]
94 US_area_codes["401"] = ["RI","Rhode Island"]
95 US_area_codes["402"] = ["NE","E Nebraska: Omaha, Lincoln"]
96 US_area_codes["403"] = ["AB","Canada: Southern Alberta"]
97 US_area_codes["404"] = ["GA","N Georgia: Atlanta and suburbs"]
98 US_area_codes["405"] = ["OK","W Oklahoma: Oklahoma City"]
99 US_area_codes["406"] = ["MT","Montana"]
100 US_area_codes["407"] = ["FL","Central Florida: Metro Orlando"]
101 US_area_codes["408"] = ["CA","Cent. Coastal California: San Jose"]
102 US_area_codes["409"] = ["TX","SE Texas: Galveston, Port Arthur, Beaumont"]
103 US_area_codes["410"] = ["MD","E Maryland: Baltimore, Annapolis, Chesapeake Bay area, Ocean City"]
104 US_area_codes["411"] = ["--","Reserved for special applications"]
105 US_area_codes["412"] = ["PA","W Pennsylvania: Pittsburgh"]
106 US_area_codes["413"] = ["MA","W Massachusetts: Springfield"]
107 US_area_codes["414"] = ["WI","SE Wisconsin: Milwaukee County"]
108 US_area_codes["415"] = ["CA","California: San Francisco County and Marin County on the north side of the Golden Gate Bridge, extending north to Sonoma County"]
109 US_area_codes["416"] = ["ON","Canada: S Cent. Ontario: Toronto"]
110 US_area_codes["417"] = ["MO","SW Missouri: Springfield"]
111 US_area_codes["418"] = ["QC","Canada: NE Quebec: Quebec"]
112 US_area_codes["419"] = ["OH","NW Ohio: Toledo"]
113 US_area_codes["423"] = ["TN","E Tennessee, except Knoxville metro area: Chattanooga, Bristol, Johnson City, Kingsport, Greeneville"]
114 US_area_codes["424"] = ["CA","S California: Los Angeles"]
115 US_area_codes["425"] = ["WA","Washington: North Tier - Everett, Bellevue"]
116 US_area_codes["430"] = ["TX","NE Texas: Tyler"]
117 US_area_codes["432"] = ["TX","W Texas: Big Spring, Midland, Odessa"]
118 US_area_codes["434"] = ["VA","E Virginia: Charlottesville, Lynchburg, Danville, South Boston, and Emporia"]
119 US_area_codes["435"] = ["UT","Rural Utah outside Salt Lake City metro"]
120 US_area_codes["438"] = ["QC","Canada: SW Quebec: Montreal city"]
121 US_area_codes["440"] = ["OH","Ohio: Cleveland metro area, excluding Cleveland"]
122 US_area_codes["441"] = ["--","Bermuda"]
123 US_area_codes["442"] = ["CA","Far north suburbs of San Diego"]
124 US_area_codes["443"] = ["MD","E Maryland: Baltimore, Annapolis, Chesapeake Bay area, Ocean City"]
125 US_area_codes["450"] = ["QC","Canada: Southeastern Quebec; suburbs outside metro Montreal"]
126 US_area_codes["456"] = ["--","Inbound International"]
127 US_area_codes["464"] = ["IL","Illinois: south suburbs of Chicago"]
128 US_area_codes["469"] = ["TX","Texas: Dallas Metro"]
129 US_area_codes["470"] = ["GA","Georgia: Greater Atlanta Metropolitan Area"]
130 US_area_codes["473"] = ["--","Grenada"]
131 US_area_codes["475"] = ["CT","Connecticut: New Haven, Greenwich, southwestern"]
132 US_area_codes["478"] = ["GA","Central Georgia: Macon"]
133 US_area_codes["479"] = ["AR","NW Arkansas: Fort Smith, Fayetteville, Springdale, Bentonville"]
134 US_area_codes["480"] = ["AZ","Arizona: East Phoenix"]
135 US_area_codes["484"] = ["PA","SE Pennsylvania: Allentown, Bethlehem, Reading, West Chester, Norristown"]
136 US_area_codes["500"] = ["--","Personal Communication Service"]
137 US_area_codes["501"] = ["AR","Central Arkansas: Little Rock, Hot Springs, Conway"]
138 US_area_codes["502"] = ["KY","N Central Kentucky: Louisville"]
139 US_area_codes["503"] = ["OR","Oregon"]
140 US_area_codes["504"] = ["LA","E Louisiana: New Orleans metro area"]
141 US_area_codes["505"] = ["NM","North central and northwestern New Mexico"]
142 US_area_codes["506"] = ["NB","Canada: New Brunswick"]
143 US_area_codes["507"] = ["MN","S Minnesota: Rochester, Mankato, Worthington"]
144 US_area_codes["508"] = ["MA","Cent. Massachusetts: Framingham; Cape Cod"]
145 US_area_codes["509"] = ["WA","E and Central Washington state: Spokane, Yakima, Walla Walla, Ellensburg"]
146 US_area_codes["510"] = ["CA","California: Oakland, East Bay"]
147 US_area_codes["511"] = ["--","Nationwide travel information"]
148 US_area_codes["512"] = ["TX","S Texas: Austin"]
149 US_area_codes["513"] = ["OH","SW Ohio: Cincinnati"]
150 US_area_codes["514"] = ["QC","Canada: SW Quebec: Montreal city"]
151 US_area_codes["515"] = ["IA","Cent. Iowa: Des Moines"]
152 US_area_codes["516"] = ["NY","New York: Nassau County, Long Island; Hempstead"]
153 US_area_codes["517"] = ["MI","Cent. Michigan: Lansing"]
154 US_area_codes["518"] = ["NY","NE New York: Albany"]
155 US_area_codes["519"] = ["ON","Canada: SW Ontario: Windsor"]
156 US_area_codes["520"] = ["AZ","SE Arizona: Tucson area"]
157 US_area_codes["530"] = ["CA","NE California: Eldorado County area, excluding Eldorado Hills itself: incl cities of Auburn, Chico, Redding, So. Lake Tahoe, Marysville, Nevada City/Grass Valley"]
158 US_area_codes["539"] = ["OK","E Oklahoma: Tulsa area"]
159 US_area_codes["540"] = ["VA","Western and Southwest Virginia: Shenandoah and Roanoke valleys: Fredericksburg, Harrisonburg, Roanoke, Salem, Lexington and nearby areas"]
160 US_area_codes["541"] = ["OR","Oregon: Eugene, Medford"]
161 US_area_codes["551"] = ["NJ","N New Jersey: Jersey City, Hackensack"]
162 US_area_codes["555"] = ["--","Reserved for directory assistance applications"]
163 US_area_codes["557"] = ["MO","SE Missouri: St Louis metro area only"]
164 US_area_codes["559"] = ["CA","Central California: Fresno"]
165 US_area_codes["561"] = ["FL","S. Central Florida: Palm Beach County"]
166 US_area_codes["562"] = ["CA","California: Long Beach"]
167 US_area_codes["563"] = ["IA","E Iowa: Davenport, Dubuque"]
168 US_area_codes["564"] = ["WA","W Washington State: Olympia, Bellingham"]
169 US_area_codes["567"] = ["OH","NW Ohio: Toledo"]
170 US_area_codes["570"] = ["PA","NE and N Central Pennsylvania: Wilkes-Barre, Scranton"]
171 US_area_codes["571"] = ["VA","Northern Virginia: Arlington, McLean, Tysons Corner"]
172 US_area_codes["573"] = ["MO","SE Missouri: excluding St Louis metro area, includes Central/East Missouri, area between St. Louis and Kansas City"]
173 US_area_codes["574"] = ["IN","N Indiana: Elkhart, South Bend"]
174 US_area_codes["575"] = ["NM","New Mexico"]
175 US_area_codes["580"] = ["OK","W Oklahoma"]
176 US_area_codes["585"] = ["NY","NW New York: Rochester"]
177 US_area_codes["586"] = ["MI","Michigan: Macomb County"]
178 US_area_codes["600"] = ["--","Canadian Services"]
179 US_area_codes["601"] = ["MS","Mississippi: Meridian, Jackson area"]
180 US_area_codes["602"] = ["AZ","Arizona: Phoenix"]
181 US_area_codes["603"] = ["NH","New Hampshire"]
182 US_area_codes["604"] = ["BC","Canada: British Columbia: Greater Vancouver"]
183 US_area_codes["605"] = ["SD","South Dakota"]
184 US_area_codes["606"] = ["KY","E Kentucky: area east of Frankfort: Ashland"]
185 US_area_codes["607"] = ["NY","S Cent. New York: Ithaca, Binghamton; Catskills"]
186 US_area_codes["608"] = ["WI","SW Wisconsin: Madison"]
187 US_area_codes["609"] = ["NJ","S New Jersey: Trenton"]
188 US_area_codes["610"] = ["PA","SE Pennsylvania: Allentown, Bethlehem, Reading, West Chester, Norristown"]
189 US_area_codes["611"] = ["--","Reserved for special applications"]
190 US_area_codes["612"] = ["MN","Cent. Minnesota: Minneapolis"]
191 US_area_codes["613"] = ["ON","Canada: SE Ontario: Ottawa"]
192 US_area_codes["614"] = ["OH","SE Ohio: Columbus"]
193 US_area_codes["615"] = ["TN","Northern Middle Tennessee: Nashville metro area"]
194 US_area_codes["616"] = ["MI","W Michigan: Holland, Grand Haven, Greenville, Grand Rapids, Ionia"]
195 US_area_codes["617"] = ["MA","Massachusetts: greater Boston"]
196 US_area_codes["618"] = ["IL","S Illinois: Centralia"]
197 US_area_codes["619"] = ["CA","S California: San Diego"]
198 US_area_codes["620"] = ["KS","S Kansas: Wichita"]
199 US_area_codes["623"] = ["AZ","Arizona: West Phoenix"]
200 US_area_codes["626"] = ["CA","E S California: Pasadena"]
201 US_area_codes["627"] = ["CA","No longer in use [was Napa, Sonoma counties"]
202 US_area_codes["628"] = ["CA","(Region unknown; perm 10/21/00)21/00)00)"]
203 US_area_codes["630"] = ["IL","W NE Illinois, western suburbs of Chicago"]
204 US_area_codes["631"] = ["NY","New York: Suffolk County, Long Island; Huntington, Riverhead"]
205 US_area_codes["636"] = ["MO","Missouri: W St. Louis metro area of St. Louis county, St. Charles County, Jefferson County area south"]
206 US_area_codes["641"] = ["IA","Iowa: Mason City, Marshalltown, Creston, Ottumwa"]
207 US_area_codes["646"] = ["NY","New York"]
208 US_area_codes["647"] = ["ON","Canada: S Cent. Ontario: Toronto"]
209 US_area_codes["649"] = ["--","Turks & Caicos Islands"]
210 US_area_codes["650"] = ["CA","California: Peninsula south of San Francisco -- San Mateo County, parts of Santa Clara County"]
211 US_area_codes["651"] = ["MN","Cent. Minnesota: St. Paul"]
212 US_area_codes["660"] = ["MO","N Missouri"]
213 US_area_codes["661"] = ["CA","California: N Los Angeles, Mckittrick, Mojave, Newhall, Oildale, Palmdale, Taft, Tehachapi, Bakersfield, Earlimart, Lancaster"]
214 US_area_codes["662"] = ["MS","N Mississippi: Tupelo, Grenada"]
215 US_area_codes["664"] = ["--","Montserrat"]
216 US_area_codes["669"] = ["CA","Cent. Coastal California: San Jose"]
217 US_area_codes["670"] = ["MP","Commonwealth of the Northern Mariana Islands (CNMI, US Commonwealth)"]
218 US_area_codes["671"] = ["GU","Guam"]
219 US_area_codes["678"] = ["GA","N Georgia: metropolitan Atlanta"]
220 US_area_codes["679"] = ["MI","Michigan: Dearborn area"]
221 US_area_codes["682"] = ["TX","Texas: Fort Worth areas"]
222 US_area_codes["684"] = ["--","American Samoa"]
223 US_area_codes["689"] = ["FL","Central Florida: Metro Orlando"]
224 US_area_codes["700"] = ["--","Interexchange Carrier Services"]
225 US_area_codes["701"] = ["ND","North Dakota"]
226 US_area_codes["702"] = ["NV","S. Nevada: Clark County, incl Las Vegas"]
227 US_area_codes["703"] = ["VA","Northern Virginia: Arlington, McLean, Tysons Corner"]
228 US_area_codes["704"] = ["NC","W North Carolina: Charlotte"]
229 US_area_codes["705"] = ["ON","Canada: NE Ontario: Sault Ste. Marie/N Ontario: N Bay, Sudbury"]
230 US_area_codes["706"] = ["GA","N Georgia: Columbus, Augusta"]
231 US_area_codes["707"] = ["CA","NW California: Santa Rosa, Napa, Vallejo, American Canyon, Fairfield"]
232 US_area_codes["708"] = ["IL","Illinois: southern and western suburbs of Chicago"]
233 US_area_codes["709"] = ["NL","Canada: Newfoundland and Labrador"]
234 US_area_codes["710"] = ["--","US Government"]
235 US_area_codes["711"] = ["--","Telecommunications Relay Services"]
236 US_area_codes["712"] = ["IA","W Iowa: Council Bluffs"]
237 US_area_codes["713"] = ["TX","Mid SE Texas: central Houston"]
238 US_area_codes["714"] = ["CA","North and Central Orange County"]
239 US_area_codes["715"] = ["WI","N Wisconsin: Eau Claire, Wausau, Superior"]
240 US_area_codes["716"] = ["NY","NW New York: Buffalo"]
241 US_area_codes["717"] = ["PA","E Pennsylvania: Harrisburg"]
242 US_area_codes["718"] = ["NY","New York City, New York"]
243 US_area_codes["719"] = ["CO","SE Colorado: Pueblo, Colorado Springs"]
244 US_area_codes["720"] = ["CO","Central Colorado: Denver"]
245 US_area_codes["724"] = ["PA","SW Pennsylvania"]
246 US_area_codes["727"] = ["FL","Florida Tampa Metro: Saint Petersburg, Clearwater"]
247 US_area_codes["731"] = ["TN","W Tennessee: outside Memphis metro area"]
248 US_area_codes["732"] = ["NJ","Cent. New Jersey: Toms River, New Brunswick, Bound Brook"]
249 US_area_codes["734"] = ["MI","SE Michigan: west and south of Detroit -- Ann Arbor, Monroe"]
250 US_area_codes["737"] = ["TX","S Texas: Austin"]
251 US_area_codes["740"] = ["OH","SE Ohio"]
252 US_area_codes["747"] = ["CA","S California: Los Angeles, Agoura Hills, Calabasas, Hidden Hills, and Westlake Village"]
253 US_area_codes["754"] = ["FL","Florida: Broward County area, incl Ft. Lauderdale"]
254 US_area_codes["757"] = ["VA","E Virginia: Tidewater / Hampton Roads area -- Norfolk, Virginia Beach, Chesapeake, Portsmouth, Hampton, Newport News, Suffolk"]
255 US_area_codes["758"] = ["--","St. Lucia"]
256 US_area_codes["760"] = ["CA","California: San Diego North County to Sierra Nevada"]
257 US_area_codes["762"] = ["GA","N Georgia: Columbus, Augusta"]
258 US_area_codes["763"] = ["MN","Minnesota: Minneapolis NW"]
259 US_area_codes["764"] = ["CA","SUSPENDED"]
260 US_area_codes["765"] = ["IN","Indiana: outside Indianapolis"]
261 US_area_codes["767"] = ["--","Dominica"]
262 US_area_codes["769"] = ["MS","Mississippi: Meridian, Jackson area"]
263 US_area_codes["770"] = ["GA","Georgia: Atlanta suburbs: outside of I-285 ring road"]
264 US_area_codes["772"] = ["FL","S. Central Florida: St. Lucie, Martin, and Indian River counties"]
265 US_area_codes["773"] = ["IL","Illinois: city of Chicago, outside the loop"]
266 US_area_codes["774"] = ["MA","Cent. Massachusetts: Framingham; Cape Cod"]
267 US_area_codes["775"] = ["NV","N. Nevada: Reno"]
268 US_area_codes["778"] = ["BC","Canada: British Columbia: Greater Vancouver"]
269 US_area_codes["779"] = ["IL","NW Illinois: Rockford, Kankakee"]
270 US_area_codes["780"] = ["AB","Canada: Northern Alberta, north of Lacombe"]
271 US_area_codes["781"] = ["MA","Massachusetts: Boston surburbs, to the north and west"]
272 US_area_codes["784"] = ["--","St. Vincent & Grenadines"]
273 US_area_codes["785"] = ["KS","N & W Kansas: Topeka"]
274 US_area_codes["786"] = ["FL","SE Florida, Monroe County"]
275 US_area_codes["787"] = ["PR","Puerto Rico"]
276 US_area_codes["800"] = ["--","US/Canada toll free"]
277 US_area_codes["801"] = ["UT","Utah: Salt Lake City Metro"]
278 US_area_codes["802"] = ["VT","Vermont"]
279 US_area_codes["803"] = ["SC","South Carolina: Columbia, Aiken, Sumter"]
280 US_area_codes["804"] = ["VA","E Virginia: Richmond"]
281 US_area_codes["805"] = ["CA","S Cent. and Cent. Coastal California: Ventura County, Santa Barbara County: San Luis Obispo, Thousand Oaks, Carpinteria, Santa Barbara, Santa Maria, Lompoc, Santa Ynez Valley / Solvang"]
282 US_area_codes["806"] = ["TX","Panhandle Texas: Amarillo, Lubbock"]
283 US_area_codes["807"] = ["ON","Canada: W Ontario: Thunder Bay region to Manitoba border"]
284 US_area_codes["808"] = ["HI","Hawaii"]
285 US_area_codes["809"] = ["--","Dominican Republic"]
286 US_area_codes["810"] = ["MI","E Michigan: Flint, Pontiac"]
287 US_area_codes["811"] = ["--","Reserved for special applications"]
288 US_area_codes["812"] = ["IN","S Indiana: Evansville, Cincinnati outskirts in IN, Columbus, Bloomington"]
289 US_area_codes["813"] = ["FL","SW Florida: Tampa Metro"]
290 US_area_codes["814"] = ["PA","Cent. Pennsylvania: Erie"]
291 US_area_codes["815"] = ["IL","NW Illinois: Rockford, Kankakee"]
292 US_area_codes["816"] = ["MO","N Missouri: Kansas City"]
293 US_area_codes["817"] = ["TX","N Cent. Texas: Fort Worth area"]
294 US_area_codes["818"] = ["CA","S California: Los Angeles: San Fernando Valley"]
295 US_area_codes["819"] = ["QC","NW Quebec: Trois Rivieres, Sherbrooke, Outaouais"]
296 US_area_codes["822"] = ["--","US/Canada toll free"]
297 US_area_codes["828"] = ["NC","W North Carolina: Asheville"]
298 US_area_codes["829"] = ["--","Dominican Republic"]
299 US_area_codes["830"] = ["TX","Texas: region surrounding San Antonio"]
300 US_area_codes["831"] = ["CA","California: central coast area from Santa Cruz through Monterey County"]
301 US_area_codes["832"] = ["TX","Texas: Houston"]
302 US_area_codes["833"] = ["--","US/Canada toll free"]
303 US_area_codes["835"] = ["PA","SE Pennsylvania: Allentown, Bethlehem, Reading, West Chester, Norristown"]
304 US_area_codes["843"] = ["SC","South Carolina, coastal area: Charleston, Beaufort, Myrtle Beach"]
305 US_area_codes["844"] = ["--","US/Canada toll free"]
306 US_area_codes["845"] = ["NY","New York: Poughkeepsie; Nyack, Nanuet, Valley Cottage, New City, Putnam, Dutchess, Rockland, Orange, Ulster and parts of Sullivan counties in New York's lower Hudson Valley and Delaware County in the Catskills"]
307 US_area_codes["847"] = ["IL","Northern NE Illinois: northwestern suburbs of chicago"]
308 US_area_codes["848"] = ["NJ","Cent. New Jersey: Toms River, New Brunswick, Bound Brook"]
309 US_area_codes["850"] = ["FL","Florida panhandle, from east of Tallahassee to Pensacola"]
310 US_area_codes["855"] = ["--","US/Canada toll free"]
311 US_area_codes["856"] = ["NJ","SW New Jersey: greater Camden area, Mt Laurel"]
312 US_area_codes["857"] = ["MA","Massachusetts: greater Boston"]
313 US_area_codes["858"] = ["CA","S California: San Diego"]
314 US_area_codes["859"] = ["KY","N and Central Kentucky: Lexington; suburban KY counties of Cincinnati OH metro area; Covington, Newport, Ft. Thomas, Ft. Wright, Florence"]
315 US_area_codes["860"] = ["CT","Connecticut: areas outside of Fairfield and New Haven Counties"]
316 US_area_codes["862"] = ["NJ","N New Jersey: Newark Paterson Morristown"]
317 US_area_codes["863"] = ["FL","Florida: Lakeland, Polk County"]
318 US_area_codes["864"] = ["SC","South Carolina, upstate area: Greenville, Spartanburg"]
319 US_area_codes["865"] = ["TN","E Tennessee: Knoxville, Knox and adjacent counties"]
320 US_area_codes["866"] = ["--","US/Canada toll free"]
321 US_area_codes["867"] = ["YT","Canada: Yukon, Northwest Territories, Nunavut"]
322 US_area_codes["868"] = ["--","Trinidad and Tobago"]
323 US_area_codes["869"] = ["--","St. Kitts & Nevis"]
324 US_area_codes["870"] = ["AR","Arkansas: areas outside of west/central AR: Jonesboro, etc"]
325 US_area_codes["872"] = ["IL","Illinois: Chicago"]
326 US_area_codes["876"] = ["--","Jamaica"]
327 US_area_codes["877"] = ["--","US/Canada toll free"]
328 US_area_codes["878"] = ["PA","Pittsburgh, New Castle"]
329 US_area_codes["880"] = ["--","Paid Toll-Free Service"]
330 US_area_codes["881"] = ["--","Paid Toll-Free Service"]
331 US_area_codes["882"] = ["--","Paid Toll-Free Service"]
332 US_area_codes["888"] = ["--","US/Canada toll free"]
333 US_area_codes["898"] = ["--","VoIP service"]
334 US_area_codes["900"] = ["--","US toll calls -- prices vary with the number called"]
335 US_area_codes["901"] = ["TN","W Tennessee: Memphis metro area"]
336 US_area_codes["902"] = ["NS","Canada: Nova Scotia, Prince Edward Island"]
337 US_area_codes["903"] = ["TX","NE Texas: Tyler"]
338 US_area_codes["904"] = ["FL","N Florida: Jacksonville"]
339 US_area_codes["905"] = ["ON","Canada: S Cent. Ontario: Greater Toronto Area -- Durham, Halton, Hamilton-Wentworth, Niagara, Peel, York, and southern Simcoe County"]
340 US_area_codes["906"] = ["MI","Upper Peninsula Michigan: Sault Ste. Marie, Escanaba, Marquette"]
341 US_area_codes["907"] = ["AK","Alaska"]
342 US_area_codes["908"] = ["NJ","Cent. New Jersey: Elizabeth, Basking Ridge, Somerville, Bridgewater, Bound Brook"]
343 US_area_codes["909"] = ["CA","California: Inland empire: San Bernardino"]
344 US_area_codes["910"] = ["NC","S Cent. North Carolina: Fayetteville, Wilmington"]
345 US_area_codes["911"] = ["--","Emergency"]
346 US_area_codes["912"] = ["GA","SE Georgia: Savannah"]
347 US_area_codes["913"] = ["KS","Kansas: Kansas City area"]
348 US_area_codes["914"] = ["NY","S New York: Westchester County"]
349 US_area_codes["915"] = ["TX","W Texas: El Paso"]
350 US_area_codes["916"] = ["CA","NE California: Sacramento, Walnut Grove, Lincoln, Newcastle and El Dorado Hills"]
351 US_area_codes["917"] = ["NY","New York: New York City"]
352 US_area_codes["918"] = ["OK","E Oklahoma: Tulsa"]
353 US_area_codes["919"] = ["NC","E North Carolina: Raleigh"]
354 US_area_codes["920"] = ["WI","NE Wisconsin: Appleton, Green Bay, Sheboygan, Fond du Lac"]
355 US_area_codes["925"] = ["CA","California: Contra Costa area: Antioch, Concord, Pleasanton, Walnut Creek"]
356 US_area_codes["927"] = ["FL","Florida: Cellular coverage in Orlando area"]
357 US_area_codes["928"] = ["AZ","Central and Northern Arizona: Prescott, Flagstaff, Yuma"]
358 US_area_codes["931"] = ["TN","Middle Tennessee: semi-circular ring around Nashville"]
359 US_area_codes["935"] = ["CA","S California: San Diego"]
360 US_area_codes["936"] = ["TX","SE Texas: Conroe, Lufkin, Nacogdoches, Crockett"]
361 US_area_codes["937"] = ["OH","SW Ohio: Dayton"]
362 US_area_codes["939"] = ["PR","Puerto Rico"]
363 US_area_codes["940"] = ["TX","N Cent. Texas: Denton, Wichita Falls"]
364 US_area_codes["941"] = ["FL","SW Florida: Sarasota and Manatee counties"]
365 US_area_codes["947"] = ["MI","Michigan: Oakland County"]
366 US_area_codes["949"] = ["CA","California: S Coastal Orange County"]
367 US_area_codes["951"] = ["CA","California: W Riverside County"]
368 US_area_codes["952"] = ["MN","Minnesota: Minneapolis SW, Bloomington"]
369 US_area_codes["954"] = ["FL","Florida: Broward County area, incl Ft. Lauderdale"]
370 US_area_codes["956"] = ["TX","Texas: Valley of Texas area; Harlingen, Laredo"]
371 US_area_codes["957"] = ["NM","New Mexico"]
372 US_area_codes["959"] = ["CT","Connecticut: Hartford, New London"]
373 US_area_codes["970"] = ["CO","N and W Colorado"]
374 US_area_codes["971"] = ["OR","Oregon: Metropolitan Portland, Salem/Keizer area, incl Cricket Wireless"]
375 US_area_codes["972"] = ["TX","Texas: Dallas Metro"]
376 US_area_codes["973"] = ["NJ","N New Jersey: Newark, Paterson, Morristown"]
377 US_area_codes["975"] = ["MO","N Missouri: Kansas City"]
378 US_area_codes["976"] = ["--","Unassigned"]
379 US_area_codes["978"] = ["MA","Massachusetts: north of Boston to NH"]
380 US_area_codes["979"] = ["TX","SE Texas: Bryan, College Station, Bay City"]
381 US_area_codes["980"] = ["NC","North Carolina:"]
382 US_area_codes["984"] = ["NC","E North Carolina: Raleigh"]
383 US_area_codes["985"] = ["LA","E Louisiana: SE/N shore of Lake Pontchartrain: Hammond, Slidell, Covington, Amite, Kentwood, area SW of New Orleans, Houma, Thibodaux, Morgan City"]
384 US_area_codes["989"] = ["MI","Upper central Michigan: Mt Pleasant, Saginaw"]
385 US_area_codes["999"] = ["--","Often used by carriers to indicate that the area code information is unavailable for CNID, even though the rest of the number is present"]