【问题标题】:How to generate UUID of image or video in android?如何在android中生成图像或视频的UUID?
【发布时间】:2013-08-02 10:32:55
【问题描述】:

我不知道如何生成某个图像或视频的 UUID。我想生成图像或视频的 UUID,以便将其发送到 web api。谁能知道该怎么做?提前致谢。

【问题讨论】:

    标签: android uuid


    【解决方案1】:

    如果您想基于图像/视频生成 UUID,那么您做错了。 UUID 代表“通用唯一标识符”。将此视为随机,但唯一标识符(数字)。

    更新2

    要生成新的 UUID(没有图像/视频的概念),您可以这样做:

    java.util.UUID.randomUUID()
    

    【讨论】:

      【解决方案2】:

      编辑 - 有一个 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;
              }
          }
      }
      

      我不能保证这在实践中是多么容易发生冲突,但如果您有各种各样的图像数据源,它可能是可用的。 -- 希望这对某人有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-07
        • 1970-01-01
        • 2019-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-27
        相关资源
        最近更新 更多