J'ai une chaîne de 18 caractères que j'ai besoin de convertir en une longue (Java) unique (en Java). Une chaîne d'échantillon serait: aaaaaaaaaaaaadnaaa p>
Ma chaîne est en fait un oracle Rowid, il peut donc être décomposé si nécessaire, voir: http: // Télécharger-UK. oracle.com/docs/cd/b19306_01/server.102/b14220/dataType.htm#cncpt713 P>
Le nombre long généré, (1) doit être unique, car aucun résultat deux ne peut pointer vers la même ligne de base de données et (2) doit être réversible, afin que je puisse récupérer la chaîne de Rowid de la longue? p>
Toute suggestion sur un algorithme à utiliser serait la bienvenue. P>
Question du forum Oracle à ce sujet Il y a quelques années: http: // forums.oracle.com/forums/thread.jspa?MessageID=1059740 p>
ro p>
7 Réponses :
Vous ne pouvez pas, avec ces exigences. P>
18 caractères de (en supposant) des lettres majuscules et minuscules 56 18 sup> ou environ 2,93348915 × 103 31 sup> combinaisons. Ceci est (chemin) plus que les combinaisons approximatives de 1,84467441 × 10 19 sup> Disponible entre 64 bits. P>
Mise à jour: strong> J'avais le mal de combinatoires, heh. Même résultat cependant. P>
Selon la documentation, il s'agit d'un codage de base 64, utilisant A-Z, A-Z, 0-9 ainsi que + et /. Donc, c'est encore pire :-)
Si des chiffres sont autorisés, faites-le encore 18 ^ ((2 * 26) +10), pire à nouveau.
Ouais, cependant, la chaîne de 18 caractères peut être divisée dans ses composants, alors je me demandais si quelque chose pouvait être fait à cause de cela: aaaaaaaaaaaadnaaa = AAA2AN - AAA - AAAADN - AAA En outre, la garantie de l'unicité ne doit réalement que Couvrir au plus 100 millions de cas .... Il est peu probable que la table de base de données soit supérieure à celle-ci!
EHM, 56 options pour chaque caractère, 18 caractères, signifie 56 ^ 18 combinaisons possibles, n'est-ce pas?
Je doute que si nous dépassions jamais la limite de numéro du nombre de 18 chiffres (1 milliard milliard, même Google a des pages indexées d'au plus 100 milliards de milliards) dans le monde réel. Donc, la mappage de la chaîne -> ne doit pas être posée avec aucune contrainte.
Cela sonne ... icky, mais je ne connais pas votre contexte, alors essayez de ne pas transmettre de jugement. 8) p>
Avez-vous envisagé de convertir les caractères de la chaîne en équivalents ASCII? P>
Addendum: Bien sûr, il est possible que les caractères semi-superflits tronquent pour s'adapter, ce qui ressemble à une option que vous pouvez avoir des commentaires. p>
Oui .... cela est arrivé avant d'être bien .... forums.oracle .com / forums / thread.jspa? MessageId = 1059740
Votre chaîne de 18 caractères représentant un codage de base 64 représente un total de 108 bits d'informations, qui est presque deux fois plus à 64 ans, nous avons un peu un problème ici si nous voulons représenter toutes les clés possibles et avoir le la représentation soit réversible. P>
La chaîne peut être divisée en 4 chiffres assez facilement. Chacun de ces 4 chiffres représente quelque chose - un numéro de bloc, un décalage dans ce bloc, peu importe. Si vous parvenez à établir des limites supérieures sur les quantités sous-jacentes telles que vous connaissez des numéros plus importants ne se produira pas (c.-à-d. Si vous trouvez un moyen d'identifier au moins 44 de ces bits qui seront toujours 0), vous pouvez modifier le reste sur un long, de façon réversible. p>
Une autre possibilité serait de détendre l'obligation que l'équivalent soit un long code>. Que diriez-vous d'un BigInteger code>? Cela faciliterait la tâche. P>
"Que diriez-vous d'une biginteger?" Ou deux longs.
J'ai brièvement envisagé que, mais deux longs est Yucky, imo. Nous travaillons dans les langues OO afin que nous puissions traiter des valeurs simples comme des entités individuelles. Pour des nombres suffisamment petits, BigInteger est I> efficace deux longs, mais il est enveloppé dans un emballage cohérent.
Bien sûr, c'est juste que nous n'allons pas faire de mathématiques. Je définirais probablement une classe avec deux champs long code> ("Tophalf" et "Bottomhalf" ou autre) et des méthodes pour convertir / des chaînes. Mais vraiment cela dépend de la raison pour laquelle le questionneur (pense qu'il) a besoin d'une longue. S'il n'a que 8 octets de stockage, alors ni Biginteger ni deux longs est possible.
Je suppose que c'est une chaîne alphanumérique de cas insensible, et donc dessinée de l'ensemble dans ce cas où vous avez p> valeurs possibles pour chaque caractère. P> [a-za-z0-9] * code> 108 bits = (108 / 8) = 13.5 bytes.
C'est en fait un codage de base 64 de sorte qu'il comprend également + code> et / code>.
OK, cela lui permet toujours de s'adapter à 6 bits par caractère cependant
Il suffit de créer une carte (Dictionnaire / HashTable) qui plante Rowid Strings à un long long (incrémenté) long. Si vous conservez deux de ces dictionnaires et de les envelopper dans une belle classe, vous aurez une recherche bidirectionnelle entre les chaînes et les identifiants longs.
pseudocode: p>
C'est ce que j'ai déjà mis en œuvre (après une enquête initiale - voir le lien Oracle Forum). Le problème est que ce cache hashmap a augmenté à la limite supérieure pour la taille d'un hashmap! Par conséquent, son être étudié à nouveau
Pourquoi ne pas utiliser une table dans votre base de données pour cela?
théoriquement, vous ne pouvez pas représenter Rowid dans un long (8 octets). Cependant, en fonction de la taille de vos bases de données (l'ensemble du serveur, non seulement de votre table), vous pourrez peut-être le coder dans une longue.
Voici la mise en page de Rowid, P>
OOOOOO-FFF-BBBBBB-RRR
L'insertion de nouvelles lignes longtemps après une table de création peut entraîner des rails radicalement différents pour les nouvelles lignes, afin que nous ne puissions donc pas vraiment y aller.
a trouvé un moyen d'extraire le railid de manière différente de la base de données ....
p> puis convertissez-le en un numéro comme si:
p>
String s = Long.toHexString( featureID );
//Place 0's at the start of the String making a Strnig of size 16
s = StringUtil.padString( s, 16, '0', true );
StringBuffer sb = new StringBuffer( s );
sb.insert( 8, '.' );
sb.insert( 13, '.' );
return sb.toString();
Jusqu'à présent, c'est presque impossible. Si c'était là, il y avait un facteur de charge de Hashtable est sorti. Cependant, si quelqu'un a une idée ..