Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java如何将字符串存储/表示为长字符串。然后从长到弦_Java_Bit Manipulation - Fatal编程技术网

Java如何将字符串存储/表示为长字符串。然后从长到弦

Java如何将字符串存储/表示为长字符串。然后从长到弦,java,bit-manipulation,Java,Bit Manipulation,如何将字符串存储/表示为长字符串?然后把它塞进一个8字节的数组 我试过/正在处理的事情 String eidString = "Awesome!"; ByteBuffer buf = ByteBuffer.allocate(8); CharBuffer cbuf = buf.asCharBuffer(); cbuf.put(eidString); byte[] eid = ByteBuffer.allocate(8).putLong(cbuf ??);

如何将字符串存储/表示为长字符串?然后把它塞进一个8字节的数组

我试过/正在处理的事情

    String eidString = "Awesome!";
    ByteBuffer buf = ByteBuffer.allocate(8);
    CharBuffer cbuf = buf.asCharBuffer();
    cbuf.put(eidString);

    byte[] eid = ByteBuffer.allocate(8).putLong(cbuf ??);
尝试2

    Long l = Long.valueOf("Awesome!");

    byte[] eid = ByteBuffer.allocate(8).putLong(l).array();

    long p = ByteBuffer.wrap(eid).getLong();

    System.out.println(p);
尝试3

String input = "hello long world";

byte[] bytes = input.getBytes();
LongBuffer tmpBuf = ByteBuffer.wrap(bytes).asLongBuffer();

long[] lArr = new long[tmpBuf.remaining()];
for (int i = 0; i < lArr.length; i++)
    lArr[i] = tmpBuf.get();

System.out.println(input);
System.out.println(Arrays.toString(lArr));
// store longs...

// ...load longs
long[] longs = { 7522537965568945263L, 7955362964116237412L };
byte[] inputBytes = new byte[longs.length * 8];
ByteBuffer bbuf = ByteBuffer.wrap(inputBytes);
for (long l : longs)
    bbuf.putLong(l);
System.out.println(new String(inputBytes));
String input=“hello long world”;
byte[]bytes=input.getBytes();
LongBuffer tmpBuf=ByteBuffer.wrap(字节).asLongBuffer();
long[]lArr=新的long[tmpBuf.remaining()];
对于(int i=0;i
要将字符串解析为长字符串,可以使用长包装类

String myString = "1500000";
Long myLong = Long.parseLong(myString);
要将其填充到8字节数组中

long value = myLong.longValue();
byte[] bytes = new byte[8];
for (int i = 0; i < bytes.length; i++) {
   long mask = 0xFF00000000000000 >> (i * 8);
   bytes[i] = (byte) (value & mask);   
}
long value=myLong.longValue();
字节[]字节=新字节[8];
for(int i=0;i>(i*8);
字节[i]=(字节)(值和掩码);
}
这个例子是big-endian

如果要将字符串编码为长字符串,则可以执行以下操作:

String myString = "HELLO";
long toLong = 0;
for (int i = 0; i < myString.length(); i++) {
   long c = (long) myString.charAt(i);
   int shift = (myString.length() - 1 - i) * 8;
   toLong += c << shift;
}
String myString=“HELLO”;
长托龙=0;
对于(int i=0;itoLong+=c您需要将字符串编码为数字并将其反转

  • 您必须确定需要的符号数。例如,64个符号需要6位。32个符号需要5位
  • 这将确定字符串的最大长度。例如,对于6位=>64/6=10个符号,对于8位=>64/8=8个符号。例如,“hello long world”将不适用,除非您假设并非所有a-z都可用
完成此操作后,您可以用解析10或36基数的相同方式对符号进行编码。要将其转换回字符串,您可以执行相反的操作(如打印10或36基数的数字)

可能的字符/符号范围是多少?
(您需要包括一个终止符号,因为字符串的长度可能不同)

您不需要这样做。字符串有一个名为getBytes()的方法。它直接为您进行转换。使用参数“Halleujah”调用以下方法

结果是

 72 97 108 108 101 108 117 106 97 104
Hallelujah

如果接受以下有限字符集:

 a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,
 A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
 0,1,2,3,4,5,6,7,8,9, , <-- space character
Java代码(32位映射):

public static long stringToLong(String s) {
  if(s.length() >10) { throw new IllegalArgumentException("String is too long: "+s); }
  long out = 0L;
  for(int i=0; i<s.length(); ++i) {
    long m = reducedMapping(s.codePointAt(i));
    if (m==-1) { throw new IllegalArgumentException("Unmapped Character in String: "+s); }
    m <<= ((9-i)*6)+4;
    out |= m;
  }
  return out;
}

public static String longToString(long l) {
  String out = "";
  long m = 0xFC00000000000000L;
  for(int i=0; i<10; ++i,m>>>=6) {
    int x =(int)( (l&m) >>> (((9-i)*6)+4));
    if(x==0) { break; }
    out += mapping[x];
  }
  return out;
}


public static long reducedMapping(int x) {
  long out=-1;
       if(x >= 97 && x <= 122) { out = (long)(x-96); } //  'a' =>  1 : 0x01
  else if(x >= 65 && x <=  90) { out = (long)(x-37); } //  'A' => 27 : 0x1B
  else if(x >= 48 && x <=  57) { out = (long)(x-+5); } //  '0' => 53 : 0x35
  else if(x == 32 )            { out = 63L;          } //  ' ' => 63 : 0x3F
  return out;
}
public static char[] mapping = {
'\n', //<-- unused/empty character
'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',' '
};
public static long stringToLong32(String s) {
      if(s.length() >12) { throw new IllegalArgumentException("String is too long: "+s); }
      long out = 0L;
      for(int i=0; i<s.length(); ++i) {
        long m = reducedMapping32(s.codePointAt(i));
        if (m==-1) { throw new IllegalArgumentException("Unmapped Character in String: "+s); }
        m <<= ((11-i)*5)+4;
        out |= m;
      }
      return out;
    }

public static String longToString32(long l) {
      String out = "";
      long m = 0xF800000000000000L;
      for(int i=0; i<12; ++i,m>>>=5) {
        int x =(int)( (l&m) >>> (((11-i)*5)+4));
        if(x==0) { break; }
        out += mapping32[x];
      }
      return out;
    }

public static long reducedMapping32(int x) {
      long out=-1;
           if(x >= 97 && x <= 122) { out = (long)(x-96); } //  'a' =>  1 : 0x01
      else if(x >= 65 && x <=  90) { out = (long)(x-64); } //  'A' =>  1 : 0x01
      else if(x >= 32 && x <= 34)  { out = (long)(x-5);  } //  ' ','!','"' => 27,28,29
      else if(x == 44 )            { out = 30L;          } //  ',' => 30 : 0x1E
      else if(x == 46 )            { out = 31L;          } //  '.' => 31 : 0x1F
      return out;
    }
public static char[] mapping32 = {
    '\n', //<-- unused/empty character
    'a','b','c','d','e','f','g','h','i','j','k','l','m',
    'n','o','p','q','r','s','t','u','v','w','x','y','z',
    ' ','!','"',',','.' 
    };
}
import java.util.Arrays;
import java.util.regex.Pattern;

public class StringAndLongConveter {

  /* .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,., */
  /*   String <--> long ID Conversion   */
  /* `'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`' */

  /* --<[ Class Members ]>-- */
  // Don't re-arrange, order-dependent initializations

  private final char[]  CHAR_MAP;
  public  final int     NUM_ACTUAL_CHARS;
  public  final int     NUM_MAPPED_CHARS;
  public  final int     BIT_COUNT;
  public  final int     MAX_NUM_CHARS;
  public  final long    ROLLING_MASK;
  public  final long    FORMAT_MASK;
  public  final long    MIN_VALUE;
  public  final long    MAX_VALUE;
  public  final Pattern REGEX_CHAR_VALIDATOR;

  public StringAndLongConveter(char[] chars) {
    if(chars == null  ) { throw new IllegalArgumentException("Cannot Pass in null reference"); }
    if(chars.length==0) { throw new IllegalArgumentException("Cannot Pass in empty set"     ); }
    CHAR_MAP             = setCharMap(chars);
    NUM_ACTUAL_CHARS     = CHAR_MAP.length;
    NUM_MAPPED_CHARS     = NUM_ACTUAL_CHARS+1;
    BIT_COUNT            = calcMinBitsNeeded();
    MAX_NUM_CHARS        = calcMaxPossibleChars();
    ROLLING_MASK         = calcRollingMask();
    FORMAT_MASK          = calcFormatMask();
    MIN_VALUE            = calcIDMinVal();
    MAX_VALUE            = calcIDMaxVal();
    REGEX_CHAR_VALIDATOR = createRegExValidator();
  }

  /* --<[ Dynamic Initialization Calculation Helper Methods ]>-- */

  //Remove duplicates
  private final char[] setCharMap(final char[] chars) {
    char[] tmp = new char[chars.length];    
    int dupes = 0;
    for(int i=0; i<chars.length; ++i) {
      boolean dupeFound = false;
      for(int j=0; !dupeFound && j<i; ++j) {
        if(chars[i]==chars[j]) {
          ++dupes;
          dupeFound = true;   
        }
      }
      if(!dupeFound) { tmp[i-dupes] = chars[i]; }
    }
    char[] out = new char[chars.length-dupes];
    if(dupes==0) { out = chars; }
    else {
      for(int i=0; i<out.length; ++i) out[i] = tmp[i];
    }
    return out;
  } 
  // calculate minimum bits necessary to encode characters uniquely
  private final int calcMinBitsNeeded() {
    if(NUM_MAPPED_CHARS==0) { return 0; }
    int val,tmp,log;
    val = NUM_MAPPED_CHARS;
    tmp = Integer.highestOneBit(val); // returns only the highest set bit
    tmp = tmp | (tmp-1);              // propagate left bits
    log = Integer.bitCount(tmp);      // count bits (logarithm base 2)
    return ((val&(val-1))==0) ? log-1 : log;
    //return one less then bit count if even power of two
  }
  //Calculate maximum number of characters that can be encoded in long
  private final int calcMaxPossibleChars() {
    return Long.SIZE/BIT_COUNT;
  }
  //Calculate rolling mask for str <--> long conversion loops
  private final long calcRollingMask() {
    long   mask = 0x0000000000000001L;
    for(int i=1; i<BIT_COUNT;     ++i) { mask  |= mask << 1; }
    for(int i=1; i<MAX_NUM_CHARS; ++i) { mask <<= BIT_COUNT; }
    return mask;
  }
  //Calculate format mask for long input format validation
  private final long calcFormatMask() {
    //propagate lest significant set bit in rolling mask & negate resulting value
    return ~(ROLLING_MASK | (ROLLING_MASK-1));
  }
  //Calculate min value of long encoding
  //doubles as format specification for unused bits
  private final long calcIDMinVal() {
    return 0xAAAAAAAAAAAAAAAAL & FORMAT_MASK;
  }
  //Calculate max value of long encoding
  private final long calcIDMaxVal(){
    char   maxChar    = CHAR_MAP[CHAR_MAP.length-1];
    char[] maxCharArr = new char[MAX_NUM_CHARS];
    Arrays.fill(maxCharArr, maxChar);
    return str2long(new String(maxCharArr));
  }

  //Dynamically create RegEx validation string for invalid characters
  private final Pattern createRegExValidator() {
    return Pattern.compile("^["+Pattern.quote(new String(CHAR_MAP))+"]+?$");
  }

  /* --<[ Internal Helper Methods ]>-- */

  private static boolean ulongLessThen(long lh, long rh) {
    return (((lh ^ rh) >> 63) == 0) ? lh < rh : (0x8000000000000000L & lh)==0;
  }

  private long charMapping(final char c) {
    for(int i=0; i<CHAR_MAP.length; ++i)
      if(CHAR_MAP[i]==c)
        return i+1;
    return -1;
  }

  /* --<[ String <--> long Conversion Methods ]>-- */

  public  final String long2str(final long n) {
    String out = "";
    if (ulongLessThen(n,MIN_VALUE) || ulongLessThen(MAX_VALUE,n)) { throw new IllegalArgumentException("Long Outside of Formatted Range: "+Long.toHexString(n)); }
    if ((FORMAT_MASK & n) != MIN_VALUE)                           { throw new IllegalArgumentException("Improperly Formatted long"); }
    long m = ROLLING_MASK;
    for(int i=0; i<MAX_NUM_CHARS; ++i,m>>>=BIT_COUNT) {
      int x =(int)( (n&m) >>> ((MAX_NUM_CHARS-i-1)*BIT_COUNT));//10|10 0111
      if(x >= NUM_MAPPED_CHARS) { throw new IllegalArgumentException("Invalid Formatted bit mapping: \nlong="+Long.toHexString(n)+"\n masked="+Long.toHexString(n&m)+"\n i="+i+" x="+x); }
      if(x==0) { break; }
      out += CHAR_MAP[x-1];
    }
    return out;
  }

  public  final long str2long(String str) {
    if(str.length() > MAX_NUM_CHARS) { throw new IllegalArgumentException("String is too long: "+str); }
    long out = MIN_VALUE;
    for(int i=0; i<str.length(); ++i) {
      long m = charMapping(str.charAt(i));
      if (m==-1) { throw new IllegalArgumentException("Unmapped Character in String: "+str); }
      m <<= ((MAX_NUM_CHARS-i-1)*BIT_COUNT);
      out += m; // += is more destructive then |= allowing errors to be more readily detected 
    }
    return out;
  }

  public  final boolean isValidString(String str) {
    return str != null && !str.equals("")               //null or empty String
       &&  str.length() <= MAX_NUM_CHARS                //too long
       &&  REGEX_CHAR_VALIDATOR.matcher(str).matches(); //only valid chars in string
  }

  public final char[] getMappedChars() { return Arrays.copyOf(CHAR_MAP,CHAR_MAP.length); }

}

玩得开心编码和解码
String
s&
long
s

嗯,你意识到你可以使用的最大字符串长度是8个字符,对吗?你的两个例子违反了这一点。你想在long中存储任意长度的字符串吗?换句话说,你想使用的字符串有最大长度吗?@stackoverflow:Java long可以存储64位的数据。因此,您可以存储任何具有64位数据的值。实际上,对于Unicode基本多语言平面,7位ASCII为9个字符,UTF-16为4个字符。@mikeslattery:4个字符,假设每个字符为16位……这可能有助于了解您为什么要转换String
转换为
long
,因为这在一般情况下是不可能的。但是我需要将诸如“Hello”之类的字符存储到long中。使用包装器类无法实现这一点。long.parseLong(“Hello”)不会work@stackoverflow:你为什么“需要”这样做?就像说,“我需要能把车停在我的背包里,但拉链没拉那么远!"当然不是,你为什么希望你的车能放在你的背包里呢?@DanielPryden我问这个问题是想看看解决方案。我带着一个字母数字的ID在一个长的UDP数据包里。我只是解码器,不是编码器。这很好,但是如果我只需要字符a呢-Z?我试图将所需的位数减少到5,从而将字符串的最大长度减少到12,但我不知道如何在这里推广算法。@Makario我稍后将为您介绍这一点today@Makario我已经用32位编码选项更新了我的答案这正是我需要的。谢谢!
import java.util.Arrays;
import java.util.regex.Pattern;

public class StringAndLongConveter {

  /* .,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,., */
  /*   String <--> long ID Conversion   */
  /* `'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`' */

  /* --<[ Class Members ]>-- */
  // Don't re-arrange, order-dependent initializations

  private final char[]  CHAR_MAP;
  public  final int     NUM_ACTUAL_CHARS;
  public  final int     NUM_MAPPED_CHARS;
  public  final int     BIT_COUNT;
  public  final int     MAX_NUM_CHARS;
  public  final long    ROLLING_MASK;
  public  final long    FORMAT_MASK;
  public  final long    MIN_VALUE;
  public  final long    MAX_VALUE;
  public  final Pattern REGEX_CHAR_VALIDATOR;

  public StringAndLongConveter(char[] chars) {
    if(chars == null  ) { throw new IllegalArgumentException("Cannot Pass in null reference"); }
    if(chars.length==0) { throw new IllegalArgumentException("Cannot Pass in empty set"     ); }
    CHAR_MAP             = setCharMap(chars);
    NUM_ACTUAL_CHARS     = CHAR_MAP.length;
    NUM_MAPPED_CHARS     = NUM_ACTUAL_CHARS+1;
    BIT_COUNT            = calcMinBitsNeeded();
    MAX_NUM_CHARS        = calcMaxPossibleChars();
    ROLLING_MASK         = calcRollingMask();
    FORMAT_MASK          = calcFormatMask();
    MIN_VALUE            = calcIDMinVal();
    MAX_VALUE            = calcIDMaxVal();
    REGEX_CHAR_VALIDATOR = createRegExValidator();
  }

  /* --<[ Dynamic Initialization Calculation Helper Methods ]>-- */

  //Remove duplicates
  private final char[] setCharMap(final char[] chars) {
    char[] tmp = new char[chars.length];    
    int dupes = 0;
    for(int i=0; i<chars.length; ++i) {
      boolean dupeFound = false;
      for(int j=0; !dupeFound && j<i; ++j) {
        if(chars[i]==chars[j]) {
          ++dupes;
          dupeFound = true;   
        }
      }
      if(!dupeFound) { tmp[i-dupes] = chars[i]; }
    }
    char[] out = new char[chars.length-dupes];
    if(dupes==0) { out = chars; }
    else {
      for(int i=0; i<out.length; ++i) out[i] = tmp[i];
    }
    return out;
  } 
  // calculate minimum bits necessary to encode characters uniquely
  private final int calcMinBitsNeeded() {
    if(NUM_MAPPED_CHARS==0) { return 0; }
    int val,tmp,log;
    val = NUM_MAPPED_CHARS;
    tmp = Integer.highestOneBit(val); // returns only the highest set bit
    tmp = tmp | (tmp-1);              // propagate left bits
    log = Integer.bitCount(tmp);      // count bits (logarithm base 2)
    return ((val&(val-1))==0) ? log-1 : log;
    //return one less then bit count if even power of two
  }
  //Calculate maximum number of characters that can be encoded in long
  private final int calcMaxPossibleChars() {
    return Long.SIZE/BIT_COUNT;
  }
  //Calculate rolling mask for str <--> long conversion loops
  private final long calcRollingMask() {
    long   mask = 0x0000000000000001L;
    for(int i=1; i<BIT_COUNT;     ++i) { mask  |= mask << 1; }
    for(int i=1; i<MAX_NUM_CHARS; ++i) { mask <<= BIT_COUNT; }
    return mask;
  }
  //Calculate format mask for long input format validation
  private final long calcFormatMask() {
    //propagate lest significant set bit in rolling mask & negate resulting value
    return ~(ROLLING_MASK | (ROLLING_MASK-1));
  }
  //Calculate min value of long encoding
  //doubles as format specification for unused bits
  private final long calcIDMinVal() {
    return 0xAAAAAAAAAAAAAAAAL & FORMAT_MASK;
  }
  //Calculate max value of long encoding
  private final long calcIDMaxVal(){
    char   maxChar    = CHAR_MAP[CHAR_MAP.length-1];
    char[] maxCharArr = new char[MAX_NUM_CHARS];
    Arrays.fill(maxCharArr, maxChar);
    return str2long(new String(maxCharArr));
  }

  //Dynamically create RegEx validation string for invalid characters
  private final Pattern createRegExValidator() {
    return Pattern.compile("^["+Pattern.quote(new String(CHAR_MAP))+"]+?$");
  }

  /* --<[ Internal Helper Methods ]>-- */

  private static boolean ulongLessThen(long lh, long rh) {
    return (((lh ^ rh) >> 63) == 0) ? lh < rh : (0x8000000000000000L & lh)==0;
  }

  private long charMapping(final char c) {
    for(int i=0; i<CHAR_MAP.length; ++i)
      if(CHAR_MAP[i]==c)
        return i+1;
    return -1;
  }

  /* --<[ String <--> long Conversion Methods ]>-- */

  public  final String long2str(final long n) {
    String out = "";
    if (ulongLessThen(n,MIN_VALUE) || ulongLessThen(MAX_VALUE,n)) { throw new IllegalArgumentException("Long Outside of Formatted Range: "+Long.toHexString(n)); }
    if ((FORMAT_MASK & n) != MIN_VALUE)                           { throw new IllegalArgumentException("Improperly Formatted long"); }
    long m = ROLLING_MASK;
    for(int i=0; i<MAX_NUM_CHARS; ++i,m>>>=BIT_COUNT) {
      int x =(int)( (n&m) >>> ((MAX_NUM_CHARS-i-1)*BIT_COUNT));//10|10 0111
      if(x >= NUM_MAPPED_CHARS) { throw new IllegalArgumentException("Invalid Formatted bit mapping: \nlong="+Long.toHexString(n)+"\n masked="+Long.toHexString(n&m)+"\n i="+i+" x="+x); }
      if(x==0) { break; }
      out += CHAR_MAP[x-1];
    }
    return out;
  }

  public  final long str2long(String str) {
    if(str.length() > MAX_NUM_CHARS) { throw new IllegalArgumentException("String is too long: "+str); }
    long out = MIN_VALUE;
    for(int i=0; i<str.length(); ++i) {
      long m = charMapping(str.charAt(i));
      if (m==-1) { throw new IllegalArgumentException("Unmapped Character in String: "+str); }
      m <<= ((MAX_NUM_CHARS-i-1)*BIT_COUNT);
      out += m; // += is more destructive then |= allowing errors to be more readily detected 
    }
    return out;
  }

  public  final boolean isValidString(String str) {
    return str != null && !str.equals("")               //null or empty String
       &&  str.length() <= MAX_NUM_CHARS                //too long
       &&  REGEX_CHAR_VALIDATOR.matcher(str).matches(); //only valid chars in string
  }

  public final char[] getMappedChars() { return Arrays.copyOf(CHAR_MAP,CHAR_MAP.length); }

}