-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(website): change creation of accession from sequence to transfor…
…med sequence
- Loading branch information
1 parent
4a22882
commit f188c11
Showing
31 changed files
with
916 additions
and
541 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
backend/src/main/kotlin/org/loculus/backend/service/GenerateAccessionFromNumberService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package org.loculus.backend.service | ||
|
||
import org.loculus.backend.config.BackendConfig | ||
import org.loculus.backend.utils.Accession | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.stereotype.Service | ||
|
||
@Service | ||
class GenerateAccessionFromNumberService( | ||
@Autowired val backendConfig: BackendConfig, | ||
) { | ||
|
||
fun generateCustomId(sequenceNumber: Long): String { | ||
val base34Digits: MutableList<Char> = mutableListOf() | ||
var remainder: Long = sequenceNumber | ||
|
||
do { | ||
val digit = (remainder % 34).toInt() | ||
base34Digits.addFirst(CODE_POINTS[digit]) | ||
remainder /= 34 | ||
} while (remainder > 0) | ||
|
||
val serialAccessionPart = base34Digits | ||
.joinToString("") | ||
.padStart(6, '0') | ||
return backendConfig.accessionPrefix + serialAccessionPart + generateCheckCharacter(serialAccessionPart) | ||
} | ||
|
||
fun validateAccession(accession: Accession): Boolean { | ||
if (!accession.startsWith(backendConfig.accessionPrefix)) { | ||
return false | ||
} | ||
return validateCheckCharacter(accession.removePrefix(backendConfig.accessionPrefix)) | ||
} | ||
|
||
// See https://en.wikipedia.org/wiki/Luhn_mod_N_algorithm for details | ||
private fun generateCheckCharacter(input: String): Char { | ||
var factor = 2 | ||
var sum = 0 | ||
|
||
for (i in input.length - 1 downTo 0) { | ||
var addend = factor * getCodePointFromCharacter(input[i]) | ||
|
||
factor = if (factor == 2) 1 else 2 | ||
|
||
addend = addend / NUMBER_OF_VALID_CHARACTERS + addend % NUMBER_OF_VALID_CHARACTERS | ||
sum += addend | ||
} | ||
|
||
val remainder = sum % NUMBER_OF_VALID_CHARACTERS | ||
val checkCodePoint = (NUMBER_OF_VALID_CHARACTERS - remainder) % NUMBER_OF_VALID_CHARACTERS | ||
return CODE_POINTS[checkCodePoint] | ||
} | ||
|
||
private fun validateCheckCharacter(input: String): Boolean { | ||
var factor = 1 | ||
var sum = 0 | ||
|
||
for (i in input.length - 1 downTo 0) { | ||
val codePoint: Int = getCodePointFromCharacter(input[i]) | ||
var addend = factor * codePoint | ||
|
||
factor = when (factor) { | ||
2 -> 1 | ||
else -> 2 | ||
} | ||
|
||
addend = addend / NUMBER_OF_VALID_CHARACTERS + addend % NUMBER_OF_VALID_CHARACTERS | ||
sum += addend | ||
} | ||
val remainder = sum % NUMBER_OF_VALID_CHARACTERS | ||
return remainder == 0 | ||
} | ||
|
||
companion object { | ||
const val CODE_POINTS = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ" | ||
fun getCodePointFromCharacter(character: Char): Int { | ||
return CODE_POINTS.indexOf(character) | ||
} | ||
const val NUMBER_OF_VALID_CHARACTERS = CODE_POINTS.length | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.