EEPROM.get returns bad data
You are saving a String object in EEPROM, which is useless. A string
object does not store the contents of your string. Instead, it just
stores:


the memory address where the actual contents (the characters) is
stored
the amount of memory allocated for this contents
the number of characters that actually make the string


This is what you are storing to, and retrieving from EEPROM. So you get
the correct number of characters (third item in the list above), but the
memory address now points to uninitialized RAM.

I suggest instead storing in the EEPROM a raw C string, i.e. an array of
8 chars (7 printable chars plus the terminating NUL). You could achieve
this by just changing the declaration of serial_number:

char serial_number[8];


For checking the validity, I would just check that it starts with "SN-"
and the last char is a NUL:

if (memcmp(serial_number, "SN-", 3) == 0 &amp;&amp; serial_number[7] == '\0') {
    ...
}


You could do a more stringent validation though, and check that the
other 4 chars are within the valid set.

Edit: to build serial_number with random chars:

strcpy(serial_number, "SN-");
for (int i = 3; i &lt; 7; i++)
  serial_number[i] = serial_characters[random(0, 36)];
serial_number[7] = '\0'; // terminating NUL