我不知道如何生成某个图像或视频的 UUID。我想生成图像或视频的 UUID,以便将其发送到 web api。谁能知道该怎么做?提前致谢。
2 回答
如果您想基于图像/视频生成 UUID,那么您做错了。UUID代表“通用唯一标识符”。将其读取为随机但唯一的标识符(数字)。
更新2
要生成新的 UUID(没有图像/视频的概念),您可以执行以下操作:
java.util.UUID.randomUUID()
编辑 - 有一个java.util.UUID.nameUUIDFromBytes( )
功能就是为了这个目的!下面的所有代码都是不必要的
这是问题提出 5 年后,但出现了一个用例,“从”图像生成 UUID 并非完全不合理。该场景是客户将图像上传到 PaaS,其内部要求 UUID 作为每个请求的一部分,以便 POST/PUT 可以是幂等的。PaaS 是所有消息驱动的架构,因此有很多队列和重试等。客户对上传没有太多控制权,他们目前所能做的就是发布二进制图像。
所以想法是在图像进入 PaaS 时从图像中“提取”一个 UUID,并使用该 UUID 来识别图像(例如“我们以前见过这个!无需继续处理”)。为什么不只是散列图像并使用该散列?因为 PaaS 的内部 API 都是基于 UUID 的,这是最快但最脏的方法。
这是 Java 中测试+代码的模型,它可以采用 PNG 或 JPG 并根据图像的内容确定性地“填充”UUID 的字节:
package com.mycompany;
import static com.google.common.base.Preconditions.checkState;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.UUID;
import javax.imageio.ImageIO;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class TestUuidFromImage {
// These must be sorted in ASCII byte-order
private static final byte[] VALID_UUID_BYTES = "0123456789ABCDEFabcdef".getBytes();
private static final byte[] VALID_UUID_16TH_BYTES = "89AB".getBytes();
@Test
public void testJpgUuid() throws IOException {
byte[] imageBytes = loadImageBytes("cat.jpg", "jpg");
assertUuid(imageBytes, UUID.fromString("ffc70144-4982-42c2-aa2b-3b456789cdef"));
}
@Test
public void testPngUuid() throws IOException {
byte[] imageBytes = loadImageBytes("dog.png", "png");
assertUuid(imageBytes, UUID.fromString("d9daccee-39dd-4c4d-855d-9376bc981c11"));
}
void assertUuid(byte[] imageBytes, UUID expectedUuid) throws IOException {
assertEquals(expectedUuid, createUuidFromBytes(imageBytes));
}
byte[] loadImageBytes(String resourcePath, String formatName) throws IOException {
BufferedImage img = ImageIO.read(getClass().getResource(resourcePath));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, formatName, baos );
baos.flush();
return baos.toByteArray();
}
/*
This loops from 0...N over the byte[] of an image, trying to "fill"
a 32-byte array with valid UUID characters. If it can do so, the
32-byte array of valid UUID characters is returned as a java.util.UUID
*/
private UUID createUuidFromBytes(byte[] bytes) {
byte[] uuidBytes = new byte[32];
int uuidByte = 0;
for (int j=0; j<bytes.length; j++) {
if (isUuidByte(uuidByte, bytes[j])) {
uuidBytes[uuidByte] = bytes[j];
uuidByte++;
}
if (uuidByte == 32) {
break;
}
}
checkState(uuidByte == 32, "Couldn't find 32 good UUID-valid bytes in the whole image!");
String uuidString = String.format("%s-%s-%s-%s-%s",
new String(Arrays.copyOfRange(uuidBytes, 0, 8)),
new String(Arrays.copyOfRange(uuidBytes, 8, 12)),
new String(Arrays.copyOfRange(uuidBytes, 12, 16)),
new String(Arrays.copyOfRange(uuidBytes, 16, 20)),
new String(Arrays.copyOfRange(uuidBytes, 20, 32))).toUpperCase();
return UUID.fromString(uuidString);
}
private boolean isUuidByte(int index, byte imageByte) {
switch (index) {
case 12:
// The leading byte of the 3rd section in UUID4s is always "4"
return '4' == imageByte;
case 16:
// The leading byte of the 4th section in UUID4s is one of "8", "9", "A" or "B"
return Arrays.binarySearch(VALID_UUID_16TH_BYTES, imageByte) >= 0;
default:
return Arrays.binarySearch(VALID_UUID_BYTES, imageByte) >= 0;
}
}
}
我不能保证这在实践中是多么容易发生碰撞,但如果你有各种各样的图像数据源,它可能是可用的。- 希望这对某人有所帮助。