Просто поместите этот код в цикл for следующим образом:
for(int i=0;i<10;i++){
int random = (int)(Math.random()* (50 + 1));
System.out.println (random);
}
В примере с четырьмя баллами это почти наверняка данные с двойным кодированием. Это выглядит так:
(естественно, оба случая выглядят одинаково)
Итак, это то, чего вы ожидали, так почему же ваш код не работал?
Во-первых, я хотел бы отослать вас к этой таблице , в которой показано преобразование cp1252 в Unicode. Я хочу, чтобы вы обратили внимание на то, что некоторые байты (например, 0x9D) недопустимы в cp1252.
Когда я представляю, как написать преобразователь cp1252 в utf8, мне нужно что-то сделать с этими байтами, которые нет в cp1252. Единственное, что я могу придумать, - это преобразовать неизвестные байты в символы Юникода с тем же значением. На самом деле, похоже, именно это и произошло. Давайте вернемся к вашему примеру с «четырьмя оценками» на один шаг назад.
Во-первых, поскольку это действительный код utf-8, давайте декодируем его с помощью:
$ perl -CO -MEncode -e '$a=decode("utf-8",
"\xC3\xA2\xE2\x82\xAC\xC5\x93" .
"four score" .
"\xC3\xA2\xE2\x82\xAC\xC2\x9D");
for $c (split(//,$a)) {printf "%x ",ord($c);}' | fmt
Это дает следующую последовательность кодовых точек Unicode:
e2 20ac 153 66 6f 75 72 20 73 63 6f 72 65 e2 20ac 9d
("fmt "- это команда unix, которая просто переформатирует текст, чтобы у нас были хорошие разрывы строк с длинными данными)
Теперь давайте представим каждый из них как байт в cp1252, но когда символ Unicode не может быть представлен в cp1252, давайте просто замените его байтом с таким же числовым значением. (Вместо значения по умолчанию, которое заключается в замене его знаком вопроса), тогда, если мы правы в отношении того, что произошло с данными, мы должны иметь действительный поток байтов utf8.
$ perl -CO -MEncode -e '$a=decode("utf-8",
"\xC3\xA2\xE2\x82\xAC\xC5\x93" .
"four score" .
"\xC3\xA2\xE2\x82\xAC\xC2\x9D");
$a=encode("cp-1252", $a, sub { chr($_[0]) } );
for $c (split(//,$a)) {printf "%x ",ord($c);}' | fmt
Третий аргумент для кодирования - когда он является подгруппой - сообщает, что делать с непредставимыми символами.
Это дает:
e2 80 9c 66 6f 75 72 20 73 63 6f 72 65 e2 80 9d
Теперь это допустимый поток байтов utf8. Не можете сказать это при осмотре? Что ж, давайте попросим perl декодировать этот поток байтов как utf8:
$ perl -CO -MEncode -e '$a=decode("utf-8",
"\xC3\xA2\xE2\x82\xAC\xC5\x93" .
"four score" .
"\xC3\xA2\xE2\x82\xAC\xC2\x9D");
$a=encode("cp-1252", $a, sub { chr($_[0]) } );
$a=decode("utf-8", $a, 1);
for $c (split(//,$a)) {printf "%x ",ord($c);}' | fmt
Передача «1» в качестве третьего аргумента декодирования гарантирует, что наш код будет квакать, если поток байтов недействителен. Это дает:
201c 66 6f 75 72 20 73 63 6f 72 65 201d
Или напечатано:
$ perl -CO -MEncode -e '$a=decode("utf-8",
"\xC3\xA2\xE2\x82\xAC\xC5\x93" .
"four score" .
"\xC3\xA2\xE2\x82\xAC\xC2\x9D");
$a=encode("cp-1252", $a, sub { chr($_[0]) } );
$a=decode("utf-8", $a, 1);
print "$a\n"'
“four score”
Итак, я думаю, что полный алгоритм должен быть таким:
.
sub demangle {
my($a) = shift;
eval { # the non-string form of eval just traps exceptions
# so that we return undef on exception
local $SIG{__WARN__} = sub {}; # No warning messages
$a = decode("utf-8", $a, 1);
encode("cp-1252", $a, sub {$_[0] <= 255 or die $_[0]; chr($_[0])});
}
}
Это основано на предположении, что на самом деле это очень редко для строки, которая не ' t all-ASCII, чтобы быть допустимым потоком байтов utf-8, если это действительно не utf-8. То есть это ' это не из тех вещей, которые случаются случайно.
РЕДАКТИРОВАТЬ ДОБАВИТЬ:
Обратите внимание, что эта техника, к сожалению, не слишком помогает в вашем примере с «Бобом». Я думаю, что эта строка также прошла два раунда преобразования cp1252-to-utf8, но, к сожалению, также были некоторые повреждения. Используя ту же технику, что и раньше, мы сначала читаем последовательность байтов как utf8 и смотрим на последовательность ссылок на символы Unicode, которые получаем:
$ perl -CO -MEncode -e '$a=decode("utf-8",
"bob\xC3\xAF\xC2\xBF\xC2\xBDs");
for $c (split(//,$a)) {printf "%x ",ord($c);}' | fmt
Это дает:
62 6f 62 ef bf bd 73
Так уж случилось, что для трех байтов ef bf bd , Unicode и cp1252 согласны. Таким образом, представление этой последовательности кодовых точек Unicode в cp1252 просто:
62 6f 62 ef bf bd 73
То есть та же последовательность чисел. На самом деле это действительный поток байтов utf-8, но то, что он декодирует, может вас удивить:
$ perl -CO -MEncode -e '$a=decode("utf-8",
"bob\xC3\xAF\xC2\xBF\xC2\xBDs");
$a=encode("cp-1252", $a, sub { chr(shift) } );
$a=decode("utf-8", $a, 1);
for $c (split(//,$a)) {printf "%x ",ord($c);}' | fmt
62 6f 62 fffd 73
То есть поток байтов utf-8, хотя и законный поток байтов utf-8, закодирован символ 0xFFFD, который обычно используется для «непереводимого символа». Я подозреваю, что здесь произошло следующее: при первом преобразовании * -to-utf8 был обнаружен символ, который он не распознал, и он был заменен на «непереводимый». Невозможно затем программно восстановить исходный символ.
Следствием этого является то, что вы не можете определить, является ли поток байтов допустимым utf8 (необходимый для этого алгоритма, который я дал выше), просто выполнив декодирование и затем ища 0xFFFD . Вместо этого вы должны использовать что-то вроде этого:
sub is_valid_utf8 {
defined(eval { decode("utf-8", $_[0], 1) })
}