PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
jetpack / jetpack_vendor / automattic / jetpack-password-checker / src / class-password-checker.php

class-password-checker.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3, at jetpack_vendor/automattic/jetpack-password-checker/src/class-password-checker.php

1,320 lines 33.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Password Checker package.
4 *
5 * @package automattic/jetpack-password-checker
6 */
7
8 namespace Automattic\Jetpack;
9
10 /**
11 * Checks passwords strength.
12 */
13 class Password_Checker {
14 /**
15 * Minimum entropy bits a password should contain. 36 bits of entropy is considered
16 * to be a reasonable password, 28 stands for a weak one.
17 *
18 * @var int
19 */
20 public $minimum_entropy_bits = 28;
21
22 /**
23 * Test results array.
24 *
25 * @var array
26 */
27 public $test_results = array();
28
29 /**
30 * Current password score.
31 *
32 * @var int
33 */
34 public $score = 0;
35
36 /**
37 * Current multiplier affecting the score.
38 *
39 * @var int
40 */
41 public $multiplier = 4;
42
43 /**
44 * A common password disallow list, which on match will immediately disqualify the password.
45 *
46 * @var array
47 */
48 public $common_passwords = array();
49
50 /**
51 * Minimum password length setting.
52 *
53 * @var int
54 */
55 public $minimum_password_length = 6;
56
57 /**
58 * User defined strings that passwords need to be tested for a match against.
59 *
60 * @var array
61 */
62 private $user_strings_to_test = array();
63
64 /**
65 * The user object for whom the password is being tested.
66 *
67 * @var mixed
68 */
69 protected $user = null;
70
71 /**
72 * The user identifier for whom the password is being tested, used if there's no user object.
73 *
74 * @var mixed
75 */
76 protected $user_id = null;
77
78 /**
79 * Creates an instance of the password checker class for the specified user, or
80 * defaults to the currently logged in user.
81 *
82 * @param mixed $user can be an integer ID, or a WP_User object.
83 */
84 public function __construct( $user = null ) {
85 if ( $user === null ) {
86 $this->user_id = get_current_user_id();
87 } elseif ( is_object( $user ) && isset( $user->ID ) ) {
88 // Existing user, using their ID.
89 $this->user_id = $user->ID;
90 } elseif ( is_object( $user ) ) {
91 // Newly created user, using existing data.
92 $this->user = $user;
93 $this->user_id = 'new_user';
94 } else {
95 $this->user_id = $user;
96 }
97
98 /**
99 * Filters the password strength enforcement settings.
100 *
101 * You can supply your own passwords that should not be used for authenticating in addition to weak and easy
102 * to guess strings for each user. For example, you can add passwords from known password databases to avoid
103 * compromised password usage.
104 *
105 * @param array $common_passwords strings that are forbidden for use as passwords.
106 */
107 $this->common_passwords = apply_filters( 'password_checker_common_passwords', $this->common_passwords );
108
109 /**
110 * Filters the password strength enforcement settings.
111 *
112 * You can modify the minimum password length using this filter.
113 *
114 * @param int $minimum_password_length minimum password length.
115 */
116 $this->minimum_password_length = apply_filters( 'password_checker_minimum_password_length', $this->minimum_password_length );
117
118 /**
119 * Filters the password strength enforcement settings.
120 *
121 * You can modify the minimum entropy bits requirement using this filter.
122 *
123 * @param int $minimum_entropy_bits minimum entropy bits requirement.
124 */
125 $this->minimum_entropy_bits = apply_filters( 'password_checker_minimum_entropy_bits', $this->minimum_entropy_bits );
126 }
127
128 /**
129 * Run tests against a password.
130 *
131 * @param string $password the password.
132 * @param bool $required_only only test against required conditions, defaults to false.
133 *
134 * @return array an array containing failed and passed test results.
135 */
136 public function test( $password, $required_only = false ) {
137 // Run the tests.
138 $results = $this->run_tests( $password, $this->get_tests(), $required_only );
139
140 // If we've failed on the required tests, return now.
141 if ( ! empty( $results['failed'] ) ) {
142 return array(
143 'passed' => false,
144 'test_results' => $results,
145 );
146 }
147
148 $entropy_bits = $this->calculate_entropy_bits( $password );
149
150 if ( $entropy_bits < $this->minimum_entropy_bits ) {
151 $results['failed'][] = array(
152 'test_name' => 'entropy_bits',
153 'explanation' => __( 'This password is too easy to guess: you can improve it by making it longer.', 'jetpack-password-checker' ),
154 );
155
156 // Suggest improvements from the regex rules the first pass skipped; without $required_only they already ran.
157 if ( $required_only ) {
158 $suggestions = $this->run_tests( $password, $this->get_tests( 'preg_match' ) );
159 $results['failed'] = array_merge( $results['failed'], $suggestions['failed'] );
160 }
161 }
162
163 return ( array(
164 'passed' => empty( $results['failed'] ),
165 'test_results' => $results,
166 ) );
167 }
168
169 /**
170 * Run the tests using the currently set up object values.
171 *
172 * @param string $password the password.
173 * @param array $tests tests to run.
174 * @param bool $required_only whether to run only required tests.
175 *
176 * @return array test results.
177 */
178 public function run_tests( $password, $tests, $required_only = false ) {
179 $results = array(
180 'passed' => array(),
181 'failed' => array(),
182 );
183
184 foreach ( $tests as $test_type => $section_tests ) {
185 foreach ( $section_tests as $test_name => $test_data ) {
186 // Skip non-required tests if required_only param is set.
187 if ( $required_only && ! $test_data['required'] ) {
188 continue;
189 }
190
191 $result = call_user_func_array( array( $this, 'test_' . $test_type ), array( $password, $test_data ) );
192 if ( $result ) {
193 $results['passed'][] = array( 'test_name' => $test_name );
194 } else {
195 $results['failed'][] = array(
196 'test_name' => $test_name,
197 'explanation' => $test_data['error'],
198 );
199
200 if ( isset( $test_data['fail_immediately'] ) ) {
201 return $results;
202 }
203 }
204 }
205 }
206
207 return $results;
208 }
209
210 /**
211 * Returns an array of tests that need to be run on password strings.
212 *
213 * @param array $sections only return specific sections with the passed keys, defaults to all.
214 *
215 * @return array test descriptions.
216 */
217 public function get_tests( $sections = false ) {
218 // Note: these should be in order of priority.
219 $tests = array(
220 'preg_match' => array(
221 'no_backslashes' => array(
222 'pattern' => '/^[^\\\\]*$/u',
223 'error' => __( 'Passwords may not contain the character "\".', 'jetpack-password-checker' ),
224 'required' => true,
225 'fail_immediately' => true,
226 ),
227 'minimum_length' => array(
228 'pattern' => '/^.{' . $this->minimum_password_length . ',}/u',
229 /* translators: %d is a number of characters in the password. */
230 'error' => sprintf( __( 'Password must be at least %d characters.', 'jetpack-password-checker' ), $this->minimum_password_length ),
231 'required' => true,
232 'fail_immediately' => true,
233 ),
234 'has_mixed_case' => array(
235 'pattern' => '/([a-z].*?[A-Z]|[A-Z].*?[a-z])/u',
236 'error' => __( 'This password is too easy to guess: you can improve it by adding additional uppercase letters, lowercase letters, or numbers.', 'jetpack-password-checker' ),
237 'required' => false,
238 ),
239 'has_digit' => array(
240 'pattern' => '/\d/u',
241 'error' => __( 'This password is too easy to guess: you can improve it by mixing both letters and numbers.', 'jetpack-password-checker' ),
242 'required' => false,
243 ),
244 'has_special_char' => array(
245 'pattern' => '/[^a-zA-Z\d]/u',
246 'error' => __( 'This password is too easy to guess: you can improve it by including special characters such as !#=?*&.', 'jetpack-password-checker' ),
247 'required' => false,
248 ),
249 ),
250 'compare_to_list' => array(
251 'not_a_common_password' => array(
252 'list_callback' => 'get_common_passwords',
253 'compare_callback' => 'negative_in_array',
254 'error' => __( 'This is a very common password. Choose something that will be harder for others to guess.', 'jetpack-password-checker' ),
255 'required' => true,
256 ),
257 'not_same_as_other_user_data' => array(
258 'list_callback' => 'get_other_user_data',
259 'compare_callback' => 'test_not_same_as_other_user_data',
260 'error' => __( 'Your password is too weak: Looks like you are including easy to guess information about yourself. Try something a little more unique.', 'jetpack-password-checker' ),
261 'required' => true,
262 ),
263 ),
264 );
265
266 /**
267 * Filters the password strength enforcement settings.
268 *
269 * You can determine the tests run and their order based on whatever criteria you wish to specify.
270 *
271 * @param array $tests tests to run.
272 */
273 $tests = apply_filters( 'password_checker_tests', $tests );
274
275 if ( ! $sections ) {
276 return $tests;
277 }
278
279 $sections = (array) $sections;
280
281 return array_intersect_key( $tests, array_flip( $sections ) );
282 }
283
284 /**
285 * Provides the regular expression tester functionality.
286 *
287 * @param string $password the password.
288 * @param array $test_data the current test data.
289 *
290 * @return bool does the test pass?
291 */
292 protected function test_preg_match( $password, $test_data ) {
293 return preg_match( $test_data['pattern'], $password );
294 }
295
296 /**
297 * Provides the comparison tester functionality.
298 *
299 * @param string $password the password.
300 * @param array $test_data the current test data.
301 *
302 * @return bool does the test pass?
303 */
304 protected function test_compare_to_list( $password, $test_data ) {
305 if (
306 ! is_callable( array( $this, $test_data['list_callback'] ) )
307 || ! is_callable( array( $this, $test_data['compare_callback'] ) )
308 ) {
309 return false;
310 }
311
312 return call_user_func(
313 array(
314 $this,
315 $test_data['compare_callback'],
316 ),
317 $password,
318 call_user_func( array( $this, $test_data['list_callback'] ) )
319 );
320 }
321
322 /**
323 * Getter for the common password list.
324 *
325 * @return array common passwords.
326 */
327 protected function get_common_passwords() {
328 return $this->common_passwords;
329 }
330
331 /**
332 * Returns the widely known user data that cannot be used in the password to avoid
333 * predictable strings.
334 *
335 * @return array user data.
336 */
337 protected function get_other_user_data() {
338 if ( empty( $this->user_id ) ) {
339 return array();
340 }
341
342 $user_data = get_userdata( $this->user_id );
343 if ( ! $user_data ) {
344 return array();
345 }
346
347 if ( isset( $user_data->ID ) ) {
348 $this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'first_name', true ) );
349 $this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'last_name', true ) );
350 $this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'nickname', true ) );
351 }
352
353 if ( isset( $user_data->user_nicename ) ) {
354 $this->add_user_strings_to_test( $user_data->user_nicename );
355 }
356
357 if ( isset( $user_data->display_name ) ) {
358 $this->add_user_strings_to_test( $user_data->display_name );
359 }
360
361 if ( isset( $user_data->first_name ) ) {
362 $this->add_user_strings_to_test( $user_data->first_name );
363 }
364
365 if ( isset( $user_data->last_name ) ) {
366 $this->add_user_strings_to_test( $user_data->last_name );
367 }
368
369 if ( isset( $user_data->user_email ) ) {
370 $email_username = substr( $user_data->user_email, 0, strpos( $user_data->user_email, '@' ) );
371 $this->add_user_strings_to_test( $email_username, '.' );
372 $this->add_user_strings_to_test( $user_data->user_email );
373 }
374
375 return $this->get_user_strings_to_test();
376 }
377
378 /**
379 * Compare the password for matches with known user data.
380 *
381 * @param string $password the password.
382 * @param array $strings_to_test known user data.
383 *
384 * @return bool does the test pass?
385 */
386 protected function test_not_same_as_other_user_data( $password, $strings_to_test ) {
387 if ( empty( $strings_to_test ) ) {
388 return false;
389 }
390
391 $password_lowercase = strtolower( $password );
392
393 foreach ( $strings_to_test as $string ) {
394 $string = strtolower( $string );
395 $string_reversed = strrev( $string );
396
397 if ( $password_lowercase === $string || $password_lowercase === $string_reversed ) {
398 return false;
399 }
400
401 // Also check for the string or reversed string with any numbers just stuck to the end to catch things like bob123 as passwords.
402 if (
403 preg_match( '/^' . preg_quote( $string, '/' ) . '\d+$/', $password_lowercase )
404 || preg_match( '/^' . preg_quote( $string_reversed, '/' ) . '\d+$/', $password_lowercase )
405 ) {
406 return false;
407 }
408 }
409
410 return true;
411 }
412
413 /**
414 * A shorthand for the not in array construct.
415 *
416 * @param mixed $needle the needle.
417 * @param array $haystack the haystack.
418 *
419 * @return bool is the needle not in the haystack?
420 */
421 protected function negative_in_array( $needle, $haystack ) {
422 return ! in_array( $needle, $haystack, true );
423 }
424
425 /**
426 * A helper function used to break a single string into its constituents so
427 * that both the full string and its constituents and any variants thereof
428 * can be tested against the password.
429 *
430 * @param string $string the string to be broken down.
431 * @param string $explode_delimiter delimiter.
432 *
433 * @return bool
434 */
435 protected function add_user_strings_to_test( $string, $explode_delimiter = ' ' ) {
436 // Don't check against empty strings.
437 if ( empty( $string ) ) {
438 return false;
439 }
440
441 $strings = explode( $explode_delimiter, $string );
442
443 // Remove any non alpha numeric characters from the strings to check against.
444 foreach ( $strings as $key => $_string ) {
445 $_string = trim( preg_replace( '/[^a-zA-Z0-9]/', '', $_string ) );
446 if ( empty( $_string ) ) {
447 continue;
448 }
449
450 $strings[ $key ] = $_string;
451 }
452
453 // Check the original too.
454 $strings[] = trim( $string );
455
456 // Check the original minus non alpha numeric characters.
457 $strings[] = trim( preg_replace( '/[^a-zA-Z0-9]/', '', $string ) );
458
459 // Remove any empty strings.
460 // Note: This will also filter out '0'.
461 $strings = array_filter( $strings );
462 if ( empty( $strings ) ) {
463 return false;
464 }
465
466 $this->user_strings_to_test = array_unique( array_merge( $this->user_strings_to_test, $strings ) );
467
468 return true;
469 }
470
471 /**
472 * Getter for the user strings array.
473 *
474 * @return array user strings.
475 */
476 protected function get_user_strings_to_test() {
477 return $this->user_strings_to_test;
478 }
479
480 /**
481 * Return a character set size that is used in the string.
482 *
483 * @param string $password the password.
484 *
485 * @return int number of different character sets in use.
486 */
487 protected function get_charset_size( $password ) {
488 $size = 0;
489
490 // Lowercase a-z.
491 if ( preg_match( '/[a-z]/', $password ) ) {
492 $size += 26;
493 }
494
495 // Uppercase A-Z.
496 if ( preg_match( '/[A-Z]/', substr( $password, 1, - 1 ) ) ) {
497 $size += 26;
498 }
499
500 // Digits.
501 if ( preg_match( '/\d/', substr( $password, 1, - 1 ) ) ) {
502 $size += 10;
503 }
504
505 // Over digits symbols.
506 if ( preg_match( '/[!|@|#|$|%|^|&|*|(|)]/', $password ) ) {
507 $size += 10;
508 }
509
510 // Other symbols.
511 if ( preg_match( '#[`|~|-|_|=|+|\[|{|\]|}|\\|\|;:\'",<\.>/\?]#', $password ) ) {
512 $size += 20;
513 }
514
515 // Spaces.
516 if ( strpos( $password, ' ' ) ) {
517 ++$size;
518 }
519
520 return $size;
521 }
522
523 /**
524 * Shorthand for getting a character index.
525 *
526 * @param string $char character.
527 *
528 * @return int the character code.
529 */
530 protected function get_char_index( $char ) {
531 $char = strtolower( $char[0] );
532 if ( $char < 'a' || $char > 'z' ) {
533 return 0;
534 } else {
535 return ord( $char[0] ) - ord( 'a' ) + 1;
536 }
537 }
538
539 /**
540 * This is the password strength calculation algorithm, based on the formula H = L(logN/log2).
541 *
542 * H = Entropy
543 * L = String length (the for iterator)
544 * N = Our charset size, via get_charset_size()
545 *
546 * @see https://en.wikipedia.org/wiki/Password_strength#Random_passwords
547 *
548 * On top of the base formula, we're also multiplying the bits of entropy for every char
549 * by 1 - (the probabily of it following the previous char)
550 * i.e.: the probablity of U following Q is ~0.84. If our password contains this pair of characters,
551 * the u char will only add ( 0.16^2 * charset_score ) to our total of entropy bits.
552 *
553 * @param string $password the password.
554 *
555 * @return float|int
556 */
557 protected function calculate_entropy_bits( $password ) {
558 $bits = 0;
559 // Calculate the score.
560 $charset_score = log( $this->get_charset_size( $password ) ) / log( 2 );
561
562 $aidx = $this->get_char_index( $password[0] );
563 $length = strlen( $password );
564
565 for ( $b = 1; $b < $length; $b++ ) {
566 $bidx = $this->get_char_index( $password[ $b ] );
567
568 // 27 = number of chars in the index (a-z,' ').
569 $c = 1.0 - $this->frequency_table[ $aidx * 27 + $bidx ];
570
571 // Increment the bits.
572 $bits += $charset_score * $c * $c;
573
574 // Move on to next pair.
575 $aidx = $bidx;
576 }
577
578 return $bits;
579 }
580
581 /**
582 * A frequency table of character pairs, starting with ' ' then ' a', ' b' [...] , 'a ', 'aa' etc.
583 *
584 * @see http://rumkin.com/tools/password/passchk.php
585 *
586 * @var array
587 */
588 public $frequency_table = array(
589 0.23653710453418866,
590 0.04577693541332556,
591 0.03449832337075375,
592 0.042918209651552706,
593 0.037390873305146524,
594 0.028509112115468728,
595 0.02350896632162123,
596 0.022188657238664526,
597 0.028429800262428927,
598 0.04357019973757107,
599 0.00913602565971716,
600 0.03223093745443942,
601 0.02235311269864412,
602 0.04438081352966905,
603 0.04512377897652719,
604 0.020055401662049863,
605 0.055903192885260244,
606 0.0024388394809739026,
607 0.035207464644991984,
608 0.07355941099285611,
609 0.036905671380667734,
610 0.026134421927394666,
611 0.023787724158040528,
612 0.011352092141711621,
613 0.0032354570637119114,
614 0.005986878553725033,
615 0.008861933226417843,
616 0.11511532293337222,
617 0.027556203528211108,
618 0.024331243621519172,
619 0.039266365359381834,
620 0.031599941682461,
621 0.014403265782183991,
622 0.015480973902901297,
623 0.027770812071730572,
624 0.00942761335471643,
625 0.039872867764980315,
626 0.0078122175244204695,
627 0.02808456043154979,
628 0.08429100451960927,
629 0.04688963405744277,
630 0.13831170724595424,
631 0.002540311998833649,
632 0.025211838460416972,
633 0.001543082081936142,
634 0.09519638431258201,
635 0.061845750109345385,
636 0.08907071001603732,
637 0.02137571074500656,
638 0.027093162268552268,
639 0.005521504592506197,
640 0.003023181221752442,
641 0.007086747339262283,
642 0.010262720513194342,
643 0.08785070710016038,
644 0.14617757690625455,
645 0.03417291150313457,
646 0.0059635515381250915,
647 0.006146668610584633,
648 0.195202799241872,
649 0.002774748505613063,
650 0.004715556203528212,
651 0.0044776206444088066,
652 0.11205481848665985,
653 0.005654468581425864,
654 0.0028820527773727946,
655 0.07383000437381543,
656 0.005516839189386207,
657 0.006496573844583759,
658 0.09843067502551392,
659 0.0027140982650532145,
660 0.0006893133109782768,
661 0.08425368129464937,
662 0.021325557661466685,
663 0.006493074792243767,
664 0.07023414491908442,
665 0.002077270739174807,
666 0.0024633328473538415,
667 0.0007744569179180639,
668 0.015413325557661468,
669 0.0011990086018370024,
670 0.13162851727657093,
671 0.10115993585070711,
672 0.0026989357049132527,
673 0.03319317684793702,
674 0.002946202070272634,
675 0.0783216212275842,
676 0.0018358361277154103,
677 0.00258813238081353,
678 0.2141688292754046,
679 0.09853681294649366,
680 0.0032482869222918796,
681 0.04359352675317102,
682 0.01993526753171016,
683 0.0036880011663507797,
684 0.008011663507799971,
685 0.12014696019827964,
686 0.0029846916460125384,
687 0.0017553579238956116,
688 0.029470185158186325,
689 0.010413179763813967,
690 0.030699518880303252,
691 0.03508499781309229,
692 0.002021285901734947,
693 0.0010613792097973467,
694 0.0005295232541186761,
695 0.009677212421635807,
696 0.010585799679253535,
697 0.17101734946785244,
698 0.07968625164018078,
699 0.007839043592360402,
700 0.005438693687126403,
701 0.0183606939787141,
702 0.2732701559994168,
703 0.004953491762647616,
704 0.007259367254701851,
705 0.008104971570199739,
706 0.13274588132380813,
707 0.004210526315789474,
708 0.004997813092287506,
709 0.017006560723137484,
710 0.007442484327161393,
711 0.016789619478058026,
712 0.08477737279486806,
713 0.005106283714827234,
714 0.0005026971861787433,
715 0.04040355736987899,
716 0.037535500801866156,
717 0.00885960052485785,
718 0.0336410555474559,
719 0.007066919376002332,
720 0.005344219273946639,
721 0.0006333284735384167,
722 0.010684939495553289,
723 0.0063064586674442345,
724 0.15386849394955532,
725 0.015049424114302375,
726 0.012162705933809595,
727 0.020425134859308938,
728 0.037366379938766583,
729 0.02157165767604607,
730 0.009373961218836564,
731 0.0173214754337367,
732 0.009616562181075958,
733 0.029522670943286193,
734 0.010154249890654615,
735 0.018600962239393497,
736 0.06362210234728094,
737 0.03157078291296107,
738 0.151603440734801,
739 0.0062329785683044175,
740 0.014775331681003062,
741 0.0020854351946347867,
742 0.1826342032366234,
743 0.0878017203674005,
744 0.054190989940224525,
745 0.010329202507654177,
746 0.012763376585508092,
747 0.0064872430383437815,
748 0.006381105117364048,
749 0.005388540603586529,
750 0.0090800408222773,
751 0.09611196967487973,
752 0.09940691062837148,
753 0.01033969966467415,
754 0.004034407348009914,
755 0.008826942703017933,
756 0.11474675608689314,
757 0.07132584924916169,
758 0.012388977985129028,
759 0.005435194634786413,
760 0.1417174515235457,
761 0.0037066627788307337,
762 0.0045802595130485495,
763 0.060800699810468,
764 0.005341886572386646,
765 0.005683627350925791,
766 0.12434932205860913,
767 0.004596588423968508,
768 0.0007534626038781163,
769 0.07107041842834232,
770 0.022361277154104096,
771 0.04784720804782038,
772 0.06277533168100306,
773 0.003441901151771395,
774 0.005828254847645429,
775 0.0009669047966175828,
776 0.009470768333576322,
777 0.002077270739174807,
778 0.12797667298440007,
779 0.08797783933518005,
780 0.005388540603586529,
781 0.0024913252660737715,
782 0.007550954949701123,
783 0.2786866890217233,
784 0.002509986878553725,
785 0.029002478495407494,
786 0.0303204548768042,
787 0.07576614666861058,
788 0.00246799825047383,
789 0.00592389561160519,
790 0.039574281965301064,
791 0.00706808572678233,
792 0.03304505029887739,
793 0.05474150750838315,
794 0.0028633911648928414,
795 0.0005073625892987316,
796 0.07293541332555767,
797 0.053528502697186175,
798 0.022566554891383584,
799 0.038151334013704616,
800 0.002716430966613209,
801 0.005049132526607377,
802 0.0009902318122175246,
803 0.008997229916897508,
804 0.0011861787432570347,
805 0.1666377022889634,
806 0.14414462749671964,
807 0.003374252806531564,
808 0.005169266656947077,
809 0.008468873013558828,
810 0.16337541915731155,
811 0.002873888321912815,
812 0.004305000728969237,
813 0.0031141565825922144,
814 0.1241172182533897,
815 0.0052800699810468,
816 0.008969237498177577,
817 0.024094474413179766,
818 0.017029887738737422,
819 0.01722700102055693,
820 0.10618457501093455,
821 0.006147834961364631,
822 0.0008269427030179326,
823 0.03303571949263741,
824 0.024188948826359528,
825 0.05213937891820965,
826 0.04505846333284735,
827 0.0035270447587111824,
828 0.006799825047383001,
829 0.0008199445983379502,
830 0.02206735675754483,
831 0.001010059775477475,
832 0.11971191135734072,
833 0.04656538854060359,
834 0.011243621519171892,
835 0.06513019390581717,
836 0.032375564951159064,
837 0.06347047674588133,
838 0.013678961947805804,
839 0.03309870243475726,
840 0.006982942119842543,
841 0.009726199154395685,
842 0.010121592068814697,
843 0.032514360693978714,
844 0.04986032949409535,
845 0.039734072022160664,
846 0.15690683773144773,
847 0.03949963551538125,
848 0.014790494241143023,
849 0.002722262720513194,
850 0.02614375273363464,
851 0.10753637556495116,
852 0.06764834523983088,
853 0.006221315060504448,
854 0.021317393206006705,
855 0.0030826651115322934,
856 0.002399183554454002,
857 0.0019069835252952323,
858 0.015595276279341012,
859 0.0925126111678087,
860 0.18437906400349907,
861 0.006538562472663654,
862 0.008719638431258201,
863 0.02116693395538708,
864 0.18241376293920394,
865 0.007290858725761773,
866 0.005976381396705059,
867 0.005629975215045925,
868 0.09721300481119698,
869 0.004810030616707975,
870 0.024303251202799244,
871 0.012954658113427612,
872 0.011057005394372358,
873 0.02733459688001166,
874 0.10135121737862662,
875 0.012016912086309959,
876 0.001055547455897361,
877 0.009027555037177431,
878 0.07162326869806095,
879 0.01007143898527482,
880 0.07297623560285756,
881 0.006741507508383147,
882 0.0036891675171307776,
883 0.0008409389123778977,
884 0.011272780288671819,
885 0.007020265344802449,
886 0.1030389269572824,
887 0.15350809155853623,
888 0.004232686980609419,
889 0.004353987461729115,
890 0.0023385333138941536,
891 0.14450386353695874,
892 0.002546143752733635,
893 0.0024470039364338824,
894 0.01200758128006998,
895 0.0981227584195947,
896 0.003161976964572095,
897 0.040695145064878264,
898 0.03460446129173349,
899 0.003908441463770229,
900 0.01598483743986004,
901 0.13107216795451232,
902 0.003129319142732177,
903 0.00032307916605919226,
904 0.04050386353695874,
905 0.05452689896486368,
906 0.03589677795597026,
907 0.07087097244496282,
908 0.006143169558244642,
909 0.008684647907858289,
910 0.0004607085580988482,
911 0.022010205569324977,
912 0.0009097536083977258,
913 0.07328765126111678,
914 0.14751421490013122,
915 0.008015162560139961,
916 0.006601545414783497,
917 0.025279486805656802,
918 0.1682449336637994,
919 0.008313748359819215,
920 0.007010934538562473,
921 0.005886572386645284,
922 0.16889575739903775,
923 0.004123050007289692,
924 0.011925936725470185,
925 0.10007289692374982,
926 0.013380376148126549,
927 0.009021723283277445,
928 0.08650823735238372,
929 0.007756232686980609,
930 0.0007243038343781893,
931 0.0026791077416533026,
932 0.02797492345823006,
933 0.032384895757399036,
934 0.04187432570345531,
935 0.00882461000145794,
936 0.0032401224668318998,
937 0.00033357632307916605,
938 0.027878116343490307,
939 0.0022277299897944304,
940 0.14333518005540166,
941 0.1725534334451086,
942 0.02781629975215046,
943 0.006909462020702727,
944 0.005264907420906838,
945 0.16661437527336345,
946 0.004325995043009185,
947 0.003334596880011664,
948 0.005312727802886718,
949 0.14024668318996938,
950 0.0013261408368566844,
951 0.003504884093891238,
952 0.006375273363464061,
953 0.04964922000291588,
954 0.008290421344219274,
955 0.09536783787724158,
956 0.05394372357486515,
957 0.005505175681586237,
958 0.005339553870826651,
959 0.01782067356757545,
960 0.006710016037323225,
961 0.05105933809593235,
962 0.002983525295232541,
963 0.002940370316372649,
964 0.0004548768041988629,
965 0.01208456043154979,
966 0.000915585362297711,
967 0.20146260387811635,
968 0.067196967487972,
969 0.006158332118384605,
970 0.025438110511736407,
971 0.07753783350342616,
972 0.1273876658405015,
973 0.009337804344656656,
974 0.07683452398308792,
975 0.0070412596588423975,
976 0.08747164309666132,
977 0.0038827817466102928,
978 0.018116926665694706,
979 0.005017641055547455,
980 0.004567429654468581,
981 0.028277008310249308,
982 0.05271555620352821,
983 0.004394809739029013,
984 0.0013343052923166642,
985 0.00411605190260971,
986 0.059621519171890944,
987 0.09073859163143316,
988 0.01446858142586383,
989 0.006770666277883074,
990 0.003425572240851436,
991 0.0004455459979588861,
992 0.010401516256013998,
993 0.005825922146085436,
994 0.10833882490158916,
995 0.007584779122321038,
996 0.016903921854497742,
997 0.02719580113719201,
998 0.0304814112844438,
999 0.02206385770520484,
1000 0.013064295086747339,
1001 0.02696369733197259,
1002 0.009581571657676046,
1003 0.026761918647033093,
1004 0.006510570053943724,
1005 0.021941390873305145,
1006 0.07042659279778393,
1007 0.05437410701268406,
1008 0.1425175681586237,
1009 0.027802303542790494,
1010 0.037690625455605774,
1011 0.0019606356611750987,
1012 0.1095623268698061,
1013 0.06157748942994606,
1014 0.044618749088788455,
1015 0.04955124653739612,
1016 0.03608689313310978,
1017 0.018381688292754043,
1018 0.003404577926811489,
1019 0.015036594255722409,
1020 0.009600233270156,
1021 0.10794693103951014,
1022 0.12447528794284882,
1023 0.0031981338387520046,
1024 0.0074716430966613205,
1025 0.003202799241871993,
1026 0.13437643971424407,
1027 0.006655197550663361,
1028 0.0036693395538708266,
1029 0.049338970695436656,
1030 0.09486863974340283,
1031 0.0015990669193760023,
1032 0.0026604461291733486,
1033 0.051775477474850555,
1034 0.0041347135150896636,
1035 0.005450357194926374,
1036 0.12030325120279925,
1037 0.04581309228750547,
1038 0.0004537104534188657,
1039 0.12425601399620935,
1040 0.025981629975215047,
1041 0.023926519900860182,
1042 0.04423385333138941,
1043 0.0017950138504155123,
1044 0.002661612479953346,
1045 0.0006333284735384167,
1046 0.008449045050298877,
1047 0.000653156436798367,
1048 0.04816678816153958,
1049 0.008625164018078437,
1050 0.0039037760606502403,
1051 0.005228750546726928,
1052 0.004531272780288672,
1053 0.0056672984400058316,
1054 0.00359585945473101,
1055 0.0032179618020119548,
1056 0.0038093016474704767,
1057 0.011452398308791368,
1058 0.002519317684793702,
1059 0.00280390727511299,
1060 0.005572824026826068,
1061 0.004554599795888614,
1062 0.004531272780288672,
1063 0.0035841959469310393,
1064 0.004400641492928998,
1065 0.0036670068523108326,
1066 0.004839189386207902,
1067 0.006258638285464354,
1068 0.004897506925207757,
1069 0.840776789619478,
1070 0.004968654322787578,
1071 0.002886718180492783,
1072 0.0019757982213150604,
1073 0.0018568304417553576,
1074 0.001691208630995772,
1075 0.09009243329931477,
1076 0.14030150167662925,
1077 0.013242746756086894,
1078 0.013746610293045632,
1079 0.027342761335471644,
1080 0.16938912377897652,
1081 0.006607377168683481,
1082 0.01661933226417845,
1083 0.008173786266219566,
1084 0.13297448607668758,
1085 0.0034675608689313307,
1086 0.016641492928998396,
1087 0.011722991689750693,
1088 0.021493512173786266,
1089 0.03430820819361423,
1090 0.10099548039072752,
1091 0.00873596734217816,
1092 0.0018323370753754193,
1093 0.020103222044029742,
1094 0.047197550663362,
1095 0.040833940807697915,
1096 0.03361189677795597,
1097 0.010844729552412887,
1098 0.005544831608106138,
1099 0.0007522962530981193,
1100 0.01525120279924187,
1101 0.00815512465373961,
1102 0.2109648636827526,
1103 0.058258055110074355,
1104 0.007181221752442048,
1105 0.043560868931331105,
1106 0.004058900714389853,
1107 0.10618107595859454,
1108 0.0062399766729844,
1109 0.004835690333867911,
1110 0.02679224376731302,
1111 0.08414637702288964,
1112 0.0030698352529523252,
1113 0.03637498177576906,
1114 0.01592885260242018,
1115 0.017413617145356466,
1116 0.008430383437818923,
1117 0.037231083248286924,
1118 0.03290275550371775,
1119 0.007538125091121154,
1120 0.004500947660008748,
1121 0.05932409972299169,
1122 0.16006764834523984,
1123 0.03309636973319726,
1124 0.007766729844000583,
1125 0.005225251494386936,
1126 0.0006321621227584196,
1127 0.012989648636827526,
1128 0.005274238227146815,
1129 0.1254503571949264,
1130 0.12852719055255868,
1131 0.0035433736696311416,
1132 0.005203090829566993,
1133 0.0019314768916751715,
1134 0.20520775623268697,
1135 0.002509986878553725,
1136 0.00343606939787141,
1137 0.027138649948972155,
1138 0.13926578218399185,
1139 0.004565096952908587,
1140 0.005614812654905963,
1141 0.00874413179763814,
1142 0.004109053797929727,
1143 0.008300918501239247,
1144 0.08270943286193323,
1145 0.002912377897652719,
1146 0.0037066627788307337,
1147 0.06909578655780726,
1148 0.03242805073625893,
1149 0.05237614812654906,
1150 0.04723487388832191,
1151 0.0038991106575302524,
1152 0.006299460562764251,
1153 0.00043388249015891526,
1154 0.020029741944889927,
1155 0.005311561452106721,
1156 0.09334072022160665,
1157 0.022940953491762648,
1158 0.024658988190698353,
1159 0.02901297565242747,
1160 0.03531593526753171,
1161 0.0758023035427905,
1162 0.013711619769645722,
1163 0.021597317393206007,
1164 0.009670214316955824,
1165 0.044728386062108175,
1166 0.010596296836273509,
1167 0.03264382563055839,
1168 0.0604822860475288,
1169 0.05489546581134276,
1170 0.11501851581863246,
1171 0.01837585653885406,
1172 0.026237060796034405,
1173 0.0011255285026971862,
1174 0.08704125965884241,
1175 0.10156349322058608,
1176 0.06660562764251349,
1177 0.023434319871701415,
1178 0.010777081207173057,
1179 0.005409534917626476,
1180 0.003123487388832191,
1181 0.0028762210234728096,
1182 0.0089995626184575,
1183 0.07518297127861205,
1184 0.2314868056568013,
1185 0.002226563639014434,
1186 0.003285610147251786,
1187 0.0027455897361131363,
1188 0.2724537104534189,
1189 0.0016655489138358362,
1190 0.0019209797346551977,
1191 0.0022137337804344656,
1192 0.17690392185449774,
1193 0.0014532730718763668,
1194 0.0024994897215337513,
1195 0.015302522233561744,
1196 0.003441901151771395,
1197 0.015303688584341741,
1198 0.09314593964134713,
1199 0.0017833503426155418,
1200 0.0005108616416387229,
1201 0.017828838023035427,
1202 0.010385187345094037,
1203 0.003168975069252078,
1204 0.01902901297565243,
1205 0.005525003644846187,
1206 0.0010088934246974776,
1207 0.0009272488700976819,
1208 0.036282840064149294,
1209 0.0022977110365942554,
1210 0.0766805656801283,
1211 0.22270418428342326,
1212 0.005283569033386791,
1213 0.007155562035282111,
1214 0.01173582154833066,
1215 0.1715620352821111,
1216 0.003925936725470185,
1217 0.004425134859308937,
1218 0.020040239101909902,
1219 0.14243242455168392,
1220 0.0016737133692958156,
1221 0.0066808572678232975,
1222 0.011980755212130047,
1223 0.012638577052048404,
1224 0.07206065024055984,
1225 0.08115701997375711,
1226 0.00710424260096224,
1227 0.0007278028867181805,
1228 0.02347630849978131,
1229 0.04595538708266512,
1230 0.01481965301064295,
1231 0.013925061962385188,
1232 0.0018125091121154687,
1233 0.00529173348884677,
1234 0.0016340574427759146,
1235 0.03072401224668319,
1236 0.0023746901880740633,
1237 0.25174165330223064,
1238 0.06673392622831317,
1239 0.00878378772415804,
1240 0.03956261845750109,
1241 0.010077270739174807,
1242 0.0844787869951888,
1243 0.00985216503863537,
1244 0.004973319725907567,
1245 0.01893220586091267,
1246 0.11200583175389998,
1247 0.0028715556203528212,
1248 0.004095057588569762,
1249 0.01202391019098994,
1250 0.01756757544831608,
1251 0.014825484764542934,
1252 0.05312961073042717,
1253 0.06746872721971132,
1254 0.003845458521650386,
1255 0.0210806239976673,
1256 0.019443067502551394,
1257 0.08017028721387957,
1258 0.01825572240851436,
1259 0.005365213587986587,
1260 0.01959702580551101,
1261 0.026184575010934536,
1262 0.02474879720075813,
1263 0.002171745152354571,
1264 0.25827321767021433,
1265 0.048050153083539875,
1266 0.01043184137629392,
1267 0.03930485493512174,
1268 0.027640180784370902,
1269 0.03294007872867765,
1270 0.006474413179763814,
1271 0.018314039947514214,
1272 0.015119405161102202,
1273 0.014706516984983233,
1274 0.005494678524566263,
1275 0.03309870243475726,
1276 0.043864120134130345,
1277 0.058996355153812505,
1278 0.06265986295378335,
1279 0.04633328473538417,
1280 0.03790756670068523,
1281 0.0004642076104388394,
1282 0.037849249161685375,
1283 0.08369966467415076,
1284 0.04999679253535501,
1285 0.02392768625164018,
1286 0.010998687855372504,
1287 0.009881323808135296,
1288 0.003867619186470331,
1289 0.012434465665548913,
1290 0.007253535500801866,
1291 0.11106225397288234,
1292 0.17624726636535937,
1293 0.008209943140399476,
1294 0.008390727511299025,
1295 0.012682898381688294,
1296 0.1825653885406036,
1297 0.001538416678816154,
1298 0.004590756670068524,
1299 0.008710307625018223,
1300 0.1299513048549351,
1301 0.002677941390873305,
1302 0.012309666132089225,
1303 0.014087184720804781,
1304 0.01199941682461,
1305 0.031246537396121883,
1306 0.07206648199445984,
1307 0.008254264470039366,
1308 0.0007033095203382417,
1309 0.007034261554162415,
1310 0.006599212713223502,
1311 0.013906400349905234,
1312 0.050098265053214755,
1313 0.007133401370462167,
1314 0.017750692520775622,
1315 0.0008257763522379356,
1316 0.03918821985712203,
1317 0.06015454147834961,
1318 );
1319 }
1320