Add prefix-checking to message

We want to make sure the message doesn't match any of the station's listed prefixes.

Also, we give a finite number of tries to generate a valid message just in case prefixes somehow cover all messages.
Make it a setting so it can be increased if needed.
This commit is contained in:
Nathan McRae 2025-02-08 12:38:55 -08:00
parent eb07e42ab0
commit c0028b2978
3 changed files with 61 additions and 18 deletions

View File

@ -176,7 +176,7 @@ public class Main extends Application {
Path nextMessagePath = stationDirPath.resolve("next-message.txt");
String messageText;
if (!Files.exists(nextMessagePath)) {
messageText = loadedStation.generateMessage();
messageText = loadedStation.generateMessage(settings.getMessageGenerationAttempts());
} else {
messageText = new String(Files.readAllBytes(nextMessagePath));
}
@ -202,9 +202,9 @@ public class Main extends Application {
System.exit(1);
}
String newMessageText = loadedStation.generateMessage();
String newMessageText = loadedStation.generateMessage(settings.getMessageGenerationAttempts());
Files.write(nextMessagePath, newMessageText.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
} catch (IOException | StationSettings.MessageGenerationException e) {
logger.log(Level.SEVERE, "Exception while posting message to station " + stationName, e);
// TODO: Notification
System.exit(1);

View File

@ -18,8 +18,8 @@ public class MainSettings {
private static final Logger logger = Logger.getLogger(Main.class.getName());
private int digitsPerGroup;
private int messageGenerationAttempts;
private String username;
private int refreshInterval;
private String selectedStationName;
private ArrayList<StationSettings> stations;
@ -27,6 +27,7 @@ public class MainSettings {
public MainSettings() {
stations = new ArrayList<>();
stations.add(new StationSettings("Station 1"));
messageGenerationAttempts = 5;
}
public static Path getSettingsFilePath() {
@ -47,6 +48,14 @@ public class MainSettings {
return stations;
}
public int getMessageGenerationAttempts() {
return messageGenerationAttempts;
}
public void setMessageGenerationAttempts(int messageGenerationAttempts) {
this.messageGenerationAttempts = messageGenerationAttempts;
}
public String getUsername() {
return username;
}
@ -55,14 +64,6 @@ public class MainSettings {
this.username = username;
}
public int getRefreshInterval() {
return refreshInterval;
}
public void setRefreshInterval(int refreshInterval) {
this.refreshInterval = refreshInterval;
}
public String getSelectedStationName() {
return selectedStationName;
}

View File

@ -7,9 +7,12 @@ import java.security.SecureRandom;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.logging.Logger;
import java.util.Random;
public class StationSettings {
private static final Logger logger = Logger.getLogger(Main.class.getName());
private String address;
private int digitsPerGroup;
private String externalProgramCommand;
@ -76,18 +79,51 @@ public class StationSettings {
return directoryPath.resolve(stationDirName);
}
public String generateMessage() {
public String generateMessage(int generationAttempts) throws MessageGenerationException {
SecureRandom random = new SecureRandom();
StringBuilder messageBuilder = new StringBuilder();
int attemptsLeft = generationAttempts;
boolean noPrefixCollisions = false;
while (!noPrefixCollisions) {
messageBuilder = new StringBuilder();
for (int i = 0; i < messageLength; i++) {
if (i > 0 && i % digitsPerGroup == 0) {
messageBuilder.append(" ");
}
messageBuilder.append(random.nextInt(10));
}
return messageBuilder.toString();
String message = messageBuilder.toString();
boolean prefixCollision = false;
for (String prefix : prefixes) {
if (message.startsWith(prefix)) {
prefixCollision = true;
}
}
if (!prefixCollision) {
noPrefixCollisions = true;
}
attemptsLeft--;
if (prefixCollision && attemptsLeft <= 0) {
throw new MessageGenerationException("Failed " + generationAttempts + " attempts to generate message without matching prefixes. Ensure prefixes are valid.");
}
}
String messageNoSpaces = messageBuilder.toString();
StringBuilder messageFormattedBuilder = new StringBuilder();
for (int i = 0; i < messageNoSpaces.length(); i++) {
if (i > 0 && i % digitsPerGroup == 0) {
messageFormattedBuilder.append(" ");
}
messageFormattedBuilder.append(messageNoSpaces.charAt(i));
}
return messageFormattedBuilder.toString();
}
public String getAddress() {
@ -197,4 +233,10 @@ public class StationSettings {
public String toString() {
return name;
}
public class MessageGenerationException extends Exception {
public MessageGenerationException(String message) {
super(message);
}
}
}