Create Unique Message Id Like whats app - java

I am creating chat application so want generate unique message id .
Is it possible never create duplicate message id.

MongoDB's ObjectId is pretty complex is probably one of the good randomness from a unique id point of view.
So you can take a sneak peek in their source code to see how they generate it.
Leaving the definition from their official documentation here for posterity:
ObjectIds are small, likely unique, fast to generate, and ordered.
ObjectId values consists of 12-bytes, where the first four bytes are a
timestamp that reflect the ObjectId’s creation, specifically:
a 4-byte value representing the seconds since the Unix epoch,
a 3-byte machine identifier,
a 2-byte process id, and
a 3-byte counter, starting with a random value.
Example of Mongo's ObjectId:
ObjectId("507f1f77bcf86cd799439011")

There could be many ways to generate one! One common way would be to generate timestamp value and use it as a id which is also unique.
For example you can do this:
public int createID(){
Date now = new Date();
int id = Integer.parseInt(new SimpleDateFormat("ddHHmmss", Locale.US).format(now));
return id; }
you can also try and make it string and add any specific string format with it to make it more unique according to ur apps need!

base on your poor description, you can create compound id. for example you can create your ides with user id+timestamp. and if you use this pattern, your user id length must be same for all ides. so if it is not, you have to add "0" befor your current id to obtain equal length for all of your user ides
for better description:
String uniquemsgid= userid+ System.currentTimeMillis();
as a matter of fact, your user have a unique id an timestamp is unique for this user.
caution: if you use only timestamp or a date with any format, this method cant guarantee a unique message id. because two user can create a message at a moment

You can make a Random randomId= new Random();
int id = randLan.nextInt(99999) + 1;
Then you check if Id is already given, and if yes, try again, if not, you have an Id.
if(randomId == someOtherId), do same process again.

You might want to use device IMEI number for this, which is always unique and quite easy to get.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Add above permission in your manifest file and then use the below two lines to get the IMEI.
TelephonyManager mngr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
long id = Long.parseLong(mngr.getDeviceId());

Related

FHIR Resource logical id generation using SHA256

I am trying to implement code that generates FHIR message from some type of input message. When I create each FHIR resources, I would need to create resource logical id that are unique and repeatedly generated.
From Microsoft's FHIR-Converter github repository, I found that they use SHA256 to hash the input string value to generate some type of 64 character id. I used the same approach to generate UUID in java. Here is code from Microsoft FHIR-Converter in .NET:
public static string GenerateUUID(string input)
{
if (string.IsNullOrWhiteSpace(input))
{
return null;
}
var bytes = Encoding.UTF8.GetBytes(input);
var algorithm = SHA256.Create();
var hash = algorithm.ComputeHash(bytes);
var guid = new byte[16];
Array.Copy(hash, 0, guid, 0, 16);
return new Guid(guid).ToString();
}
It generates uuid like this: e40b96a6-e62e-a67e-3ac7-69a099830e1c
My questions are:
In order to repeatedly generate the same id, does the string input MUST be same as well? Meaning, if I have an input of 123, it will generate e40b96a6-e62e-a67e-3ac7-69a099830e1c all the time?
If I HAVE to use unique id in order to generate this uuid, what is the advantage of using this extra step? If my input always have unique id for each resources, can I just assign id to be (Resource name)-(id)?
Is there a way to generate id without having unique id? I have some resources that do not have something unique. Are there other techniques where I can generate a unique input that can be repeated in different platforms? I don't see how I can do this without providing unique id from input..
A given string will always generate the same id. A different string should generate a different id, though there's a very slim chance of two strings generating the same hash.
There are rules for the format of the id (only certain characters permitted, maximum length allowed), but other than that, no obvious benefit I can see. It's fine to use your 'native' identifier as the resource id. (That said, resource ids generally shouldn't be real-world identifiers like social security numbers, license numbers, etc. as that can leak protected information.)
The expectation in FHIR is that a unique resource id corresponds to a unique real-world object. If you don't have a real identifier on the object, there's a possibility you could have multiple instances that correspond to distinct real-world objects. E.g. multiple Practitioner instances where all you have is a name of "A. Smith" would not be appropriate to presume are always the same instance. If you have no 'identity', you might be better off using the 'contained' mechanism rather than generating an id just from the content.

How to convert Instant to Int

In my app I have AlarmManager to set Scheduled notification.
In order to have unique notification to each Item, I need to set unique id to each pending intent, otherwise the notification run over each other.
my problem is that my PK is string, not an int. my closest thing to Int in my Item model is Instant, which represent the time that the notification should send, and It's unique.
And because PendingIntent id is only an int, how can I convert Instant to Int?
Or should I take another approach and create data field in my model just to hold the pending intent ID?
In my understanding I shoudn't convert it directly cause it will mess with the date/time and potentially(?) won't by unique
That should work I think:
instant.get(ChronoField.INSTANT_SECONDS)
Simple String to int conversion could made with hashCode. But a hash code is by definition not unique. If possible then changing the type from int to String is probably the best option. If you really need a conversion I would recommend you create something like and IndexProvider.
public interface IndexProvider {
/**
* Idempotent index provider for id conversion.
* Be aware of memory consumption because the implementations are allowed to cache id's.
* #param id unique id
* #return a cached unique id or a new unique id
*/
int getIndex(String id);
}
This would allow you to simple solve the problem. You could use a map in the implementation for holding the String id's . Other idea would be to solve this problem in the database. For example a new table which holds you an int id for every String id. At the end you will have to modify something and you will have Pro's and Contra's for every approach.
This is probably not a full answer but I have not enough reputation for commenting.

Can firebase generate an unique ID as we wish?

Like firebase generating uid. Can firebase generate an unique ID as we wish? If it is possible? how to write a code for it in the following order?
For example PRO00013, PRO00014, PRO00015....
I am asking here, because I'm working in a project for online shopping. when a user adds a product to their inventory it needs to assign an id for every product. that is must be in the human readable format. If it is not possible, just tell me no, I can accept that answer.
You can just call .push() to get randomUUID and then ref.child(randomUUID).setValue(object)
where the object can contain field ID such as PRO00013.
If this doesn't fit your needs you can just place ref.child("PRO00013").setValue(object) and not include field id in this object.
Now you want to get id PRO00014 for the next pushed object. This ain't gonna happen with firebase.
But you can get the last ID added in this ref with query on
ref.orderByKey().limitToLast(1);
Now you have the last added object from this node and you can simply get the key which will be PRO00013.
1. Cast it to String
2. Remove "PRO" from this string
3. Cast the remaining to integer
4. Add 1 to this integer
5. Create new string variable and give it value "PRO" + the new integer
6. Now push the object in ref.(the new string variable).setValue(object).
Now I don't know if you gonna implement this logic in a cloud function accepting some sort of params but if this is the case - this should work just fine.
I also want to know WHY xD

Auto-generating a unique varchar field - mySQL, Java, Hibernate

Background : I have a database table called Contact. All users of my system have details of their contacts in this table including a firstname, a lastname, and also a varchar field called 'UniqueId'. Users of the system may put anything in the UniqueId field, as long as it is unique from that user's other contact's unique ids.
Aim : I now need to change my code so a unique id is automatically generated if the user does not provide one. This should be short and visually pleasing. Ideally it could just be an auto-incrementing number. However, AUTO_INCREMENT works for an integer field, not a varchar field.
Also note that each contact UniqueId needs to be unique from the other contacts of that user, but not neccesarily unique to the entire system. Therefore, the following UniqueIds are valid :
Contact
UserId Firstname Lastname UniqueId
1 Bob Jones 1
1 Harold Smith 2
2 Joe Bloggs 1
Question : So, how can I achieve this? Is there a reliable and clean way to get the database to generate a unique id for each contact in the existing UniqueId varchar field (Which is my preference if possible)? Or am I forced to make Java go and get the next available unique id, and if so, what is the most reliable way of doing this? Or any alternative solution?
Edit - 11th April AM: We use hibernate to map our fields. I'm just beginning to research if that may provide an alternative solution? Any opinions?
Edit - 11th April PM: 2 options are currently standing out, but neither seem as ideal as I would like.
1. As #eis suggests, I could have an auto-incrementing field in addition to my current varchar field. Then, either when a contact is saved the int can also be saved in the varchar field, or when a contact is retrieved the int can be used if the varchar is empty. But it feels messy and wrong to use two fields rather than one
2. I am looking into using a hibernate generator, as discussed here. But this involves holding a count elsewhere of the next id, and Java code, and seems to massively overcomplicate the process.
If my existing uniqueId field had been an int field, AUTO_INCREMENT would simply work, and work nicely. Is there no way to make the database generate this but save it as a String?
I think what you really should do is ditch your current 'uniqueid' and generate new ones that are really unique across the system, being always autogenerated and never provided by the user. You would need to do separate work to migrate to the new system. That's the only way I see to keep it sane. User could provide something like an alias to be more visually pleasing, if needs be.
On the upside, you could use autoincrement then.
Ok, one additional option, if you really really want what you're asking. You could have a prefix like §§§§ that is never allowed for a user, and always autogenerate ids based on that, like §§§§1, §§§§2 etc. If you disallow anything starting with that prefix from the end user, you would know that there would be no collisions, and you could just generate them one-by-one whenever needed.
Sequences would be ideal to generate numbers to it. You don't have sequences in MySQL, but you could emulate them for example like this.
I apologize, I really don't know MySQL syntax, but here's how I'd do it in SQL Server. Hopefully that will still have some value to you. Basically, I'm just counting the number of existing contacts and returning it as a varchar.
CREATE FUNCTION GetNewUniqueId
(#UserId int)
RETURNS varchar(3)
AS
BEGIN
DECLARE #Count int;
SELECT #Count = COUNT(*)
FROM Contacts
WHERE UserId = #UserId;
SET #Count = #Count + 1;
RETURN CAST(#Count AS varchar(3));
END
But if you really want something "visually pleasing," why not try returning something more like Firstname + Lastname?
CREATE FUNCTION GetNewUniqueId
(#UserId int, #FirstName varchar(255), #LastName varchar(255))
RETURNS varchar(515)
AS
BEGIN
DECLARE #UniqueId varchar(515), #Count int;
SET #UniqueId = #FirstName + #LastName;
SELECT #Count = COUNT(*)
FROM Contacts
WHERE UserId = #UserId AND LEFT(UniqueId, LEN(#UniqueId)) = #UniqueId;
IF #Count > 0
SET #UniqueId = #UniqueId + '_' + CAST(#Count + 1 AS varchar(3));
RETURN #UniqueId;
END

Unique serial number in a java web application

I've been wondering what's the correct practice for generating unique ids? The thing is in my web app I'll have a plugin system, when a user registers a plugin I want to generate a unique serial ID for it. I've been thinking about storing all numbers in a DB or a file on the server, generating a random number and checking whether it already exists in the DB/file, but that doesn't seem that good. Are there other ways to do it? Would using the UUID be the preferred way to go?
If the ids are user-facing, which it seems they are, then you want them to be difficult to guess. Use the built-in UUID class, which generates random ids for you and can format them nicely for you. Extract:
UUID idOne = UUID.randomUUID();
UUID idTwo = UUID.randomUUID();
log("UUID One: " + idOne);
log("UUID Two: " + idTwo);
Example output:
UUID One: 067e6162-3b6f-4ae2-a171-2470b63dff00
UUID Two: 54947df8-0e9e-4471-a2f9-9af509fb5889
There are other solutions in the link provided. I think it compares the methods quite well, so choose the one which best suits your needs.
Another interesting method is the one MongoDB uses, but this is possibly overkill for your needs:
A BSON ObjectID is a 12-byte value
consisting of a 4-byte timestamp
(seconds since epoch), a 3-byte
machine id, a 2-byte process id, and a
3-byte counter. Note that the
timestamp and counter fields must be
stored big endian unlike the rest of
BSON
If they weren't user facing, then you could just leave it to the database to do an auto-incrementing id: 1, 2, 3, etc.
Why not go for a static (or, in this case, a context-scoped) AtomicInteger that would be incremented when a plugin is registered ?
You could base it on user ID and timestamp, ensuring uniqueness but also providing a certain "readability"? E.g. User ID = 101, timestamp = 23 Dec 2010 13:54, you could give it ID:
201012231354101
or
101201012231354
The alternative UUID is obviously guaranteed to be unique but takes up a lot of DB space, and is quite unwieldy to work with.
A final idea is to ask your central DB for a unique ID, e.g. Oracle has sequences, or MySQL uses AUTO_INCREMENT fields, to assign unique integers.

Categories