-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSecretWR.java
More file actions
164 lines (146 loc) · 5.99 KB
/
SecretWR.java
File metadata and controls
164 lines (146 loc) · 5.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Random;
public class SecretWR {
public static final int KILOBYTE = 1024;
public static void main(final String[] args) {
final var console = System.console();
if (console == null) {
System.err.println("Ошибка: Консоль недоступна. Запустите программу в терминале.");
return;
}
try {
// 1. Ввод сида (скрыто)
final var seedInput = console.readPassword("Введите сид (скрыто): ");
if (seedInput == null || seedInput.length == 0) {
System.err.println("Ошибка: Сид не может быть пустым.");
return;
}
final var seed = SecretWR.parseSeed(seedInput);
// Очищаем память
SecretWR.wipe(seedInput);
// 2. Ввод длины файла
final var lengthStr = console.readLine("Введите длину файла (например, 10G, 500M, 1024K или число байт): ");
if (lengthStr == null || lengthStr.trim().isEmpty()) {
System.err.println("Ошибка: Длина файла не указана.");
return;
}
final var totalSizeBytes = SecretWR.parseSize(lengthStr);
if (totalSizeBytes <= 0) {
System.err.println("Ошибка: Длина должна быть положительной.");
return;
}
// 3. Ввод пути к файлу
final var pathStr = console.readLine("Введите путь для сохранения файла: ");
if (pathStr == null || pathStr.trim().isEmpty()) {
System.err.println("Ошибка: Путь к файлу не указан.");
return;
}
final var filePath = Path.of(pathStr);
// 4. Буфер для записи 10 МБ
final var bufferSize = 10 * SecretWR.KILOBYTE * SecretWR.KILOBYTE;
final var buffer = new byte[bufferSize];
// 5. Открываем файл
try (var raf = new RandomAccessFile(filePath.toFile(), "rw")) {
// Выделяем место заранее
raf.setLength(totalSizeBytes);
var remaining = totalSizeBytes;
final var random = new Random(seed);
while (remaining > 0) {
random.nextBytes(buffer);
final var toWrite = (int) Math.min(buffer.length, remaining);
raf.write(buffer, 0, toWrite);
remaining -= toWrite;
System.out.printf("\rЗаписано: %.2f%%",
((double) (totalSizeBytes - remaining) / totalSizeBytes) * 100);
}
System.out.println();
System.out.printf("Успешно записано %d байт в файл: %s%n", totalSizeBytes, filePath.toAbsolutePath());
}
} catch (final NumberFormatException e) {
System.err.println("Ошибка: Некорректный формат числа: " + e.getMessage());
} catch (final IOException e) {
System.err.println("Ошибка ввода-вывода: " + e.getMessage());
} catch (final Exception e) {
System.err.println("Неизвестная ошибка: " + e.getMessage());
}
}
/**
* Преобразует массив символов в long без создания строк
*
* @param input входной массив символов (цифры и опционально '-' в начале)
* @return число типа long
* @throws NumberFormatException если вход содержит недопустимые символы,
* значение выходит за пределы long или введён
* только минус
*/
public static long parseSeed(final char[] input) {
if (input == null || input.length == 0) {
throw new NumberFormatException("Входной массив пуст");
}
var negative = false;
var i = 0;
// Проверяем наличие минуса
if (input[0] == '-') {
if (input.length == 1) {
throw new NumberFormatException("Введён только минус, число не указано");
}
negative = true;
i = 1;
}
var result = 0L;
for (; i < input.length; i++) {
final var c = input[i];
if (c < '0' || c > '9') {
throw new NumberFormatException("Недопустимый символ: " + c);
}
final var digit = c - '0';
// Проверка переполнения в зависимости от знака
if (negative) {
// Для отрицательных чисел: result * 10 - digit <= Long.MIN_VALUE
if (result < (Long.MIN_VALUE + digit) / 10) {
throw new NumberFormatException("Значение выходит за пределы long");
}
result = result * 10 - digit;
} else {
// Для положительных чисел: result * 10 + digit > Long.MAX_VALUE
if (result > (Long.MAX_VALUE - digit) / 10) {
throw new NumberFormatException("Значение выходит за пределы long");
}
result = result * 10 + digit;
}
}
return result;
}
/**
* Преобразует строку вида "10G", "500M", "1024K", "123456789" в число байт
*/
private static long parseSize(String input) {
input = input.trim().toUpperCase();
if (input.isEmpty()) {
return -1;
}
final var suffix = input.charAt(input.length() - 1);
if (Character.isDigit(suffix)) {
// Без суффикса — просто байты
return Long.parseLong(input);
}
// Извлекаем число и множитель
final var multiplier = switch (suffix) {
case 'K' -> SecretWR.KILOBYTE;
case 'M' -> SecretWR.KILOBYTE * SecretWR.KILOBYTE;
case 'G' -> SecretWR.KILOBYTE * SecretWR.KILOBYTE * SecretWR.KILOBYTE;
default -> throw new IllegalArgumentException("Неизвестный суффикс: " + suffix);
};
final var numberPart = input.substring(0, input.length() - 1);
return Long.parseLong(numberPart) * multiplier;
}
/**
* Очищаем массив символов (для безопасности)
*/
private static void wipe(final char[] arr) {
Arrays.fill(arr, '\0');
}
}